-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDriver.vb
More file actions
650 lines (561 loc) · 26.2 KB
/
Driver.vb
File metadata and controls
650 lines (561 loc) · 26.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
' --------------------------------------------------------------------------------
'
' ASCOM Switch driver for RR4005i
'
' Description: An ASCOM Switch driver to allow management of the West Mountain
' Radio RIGRunner 4005i.
' http://www.westmountainradio.com/product_info.php?products_id=rr_4005i
'
' Implements: ASCOM Switch interface version: 1.0
'
' Edit Log:
'
' See https://github.com/EorEquis/RR4005i-Switch
'
' Your driver's ID is ASCOM.RR4005i.Switch
'
' The Guid attribute sets the CLSID for ASCOM.DeviceName.Switch
' The ClassInterface/None addribute prevents an empty interface called
' _Switch from being created and used as the [default] interface
'
' This definition is used to select code that's only applicable for one device type
#Const Device = "Switch"
Imports System.Threading
Imports ASCOM
Imports ASCOM.Astrometry
Imports ASCOM.Astrometry.AstroUtils
Imports ASCOM.DeviceInterface
Imports ASCOM.Utilities
Imports System
Imports System.Collections
Imports System.Collections.Generic
Imports System.Globalization
Imports System.Runtime.InteropServices
Imports System.Text
Imports System.Net
Imports System.Xml
<Guid("da08b3e4-17f3-49f5-96bf-8e7ec2910459")> _
<ClassInterface(ClassInterfaceType.None)> _
Public Class Switch
' The Guid attribute sets the CLSID for ASCOM.RR4005i.Switch
' The ClassInterface/None addribute prevents an empty interface called
' _RR4005i from being created and used as the [default] interface
Implements ISwitchV2
#Region "Variables"
' Driver ID and descriptive string that shows in the Chooser
Friend Shared driverID As String = "ASCOM.RR4005i.Switch"
Private Shared driverDescription As String = "RR4005i Switch"
'Constants used for Profile persistence
Friend Shared traceStateProfileName As String = "Trace Level"
Friend Shared traceStateDefault As String = "False"
Friend Shared IPProfileName As String = "IP Address"
Friend Shared IPDefault As String = "0.0.0.0"
Friend Shared portNamesProfileName As String = "Port Name"
Friend Shared portNameDefault(24) As String ' Filled later in constructor
Friend Shared deviceNameProfileName As String = "Device Name"
Friend Shared deviceNameDefault As String = "RR4005i"
Friend Shared numberOfUnitsProfileName As String = "Number Of Units"
Friend Shared numberOfUnitsDefault As String = "1"
Friend Shared maxSwitchesProfileName As String = "Max Switches"
Friend Shared maxSwitchesDefault As String = "5"
Friend Shared fetchNamesProfileName As String = "Fetch Port Names"
Friend Shared fetchNamesDefault As String = "True"
' Variables to hold the currrent device configuration
Friend Shared traceState As Boolean
Friend Shared RRIP(4) As String
Friend Shared PortNames(24) As String
Friend Shared DeviceNames(4) As String
Friend Shared NumUnits As Integer
Friend Shared bFetchNames As Boolean
Friend Shared numSwitches As Integer
Private connectedState As Boolean ' Private variable to hold the connected state
Private utilities As Util ' Private variable to hold an ASCOM Utilities object
Private astroUtilities As AstroUtils ' Private variable to hold an AstroUtils object to provide the Range method
Private TL As TraceLogger ' Private variable to hold the trace logger object (creates a diagnostic log file with information that you specify)
#End Region
#Region "Constructor"
' Constructor - Must be public for COM registration!
Public Sub New()
ReadProfile() ' Read device configuration from the ASCOM Profile store
TL = New TraceLogger("", "RR4005i")
TL.Enabled = traceState
TL.LogMessage("Switch", "Starting initialisation")
connectedState = False ' Initialise connected to false
utilities = New Util() ' Initialise util object
astroUtilities = New AstroUtils 'Initialise new astro utiliites object
' Basically just laziness. I didn't want to type all 25 default port names.
For i As Integer = 0 To 24
portNameDefault(i) = "Port " & (i + 1).ToString
Next
TL.LogMessage("Switch", "Completed initialisation")
End Sub
#End Region
#Region "Common properties and methods"
''' <summary>
''' Displays the Setup Dialog form.
''' If the user clicks the OK button to dismiss the form, then
''' the new settings are saved, otherwise the old values are reloaded.
''' THIS IS THE ONLY PLACE WHERE SHOWING USER INTERFACE IS ALLOWED!
''' </summary>
Public Sub SetupDialog() Implements ISwitchV2.SetupDialog
' consider only showing the setup dialog if not connected
' or call a different dialog if connected
If IsConnected Then
System.Windows.Forms.MessageBox.Show("Already connected, just press OK")
End If
Using F As SetupDialogForm = New SetupDialogForm()
Dim result As System.Windows.Forms.DialogResult = F.ShowDialog()
If result = DialogResult.OK Then
WriteProfile() ' Persist device configuration values to the ASCOM Profile store
End If
End Using
End Sub
Public ReadOnly Property SupportedActions() As ArrayList Implements ISwitchV2.SupportedActions
Get
TL.LogMessage("SupportedActions Get", "Returning empty arraylist")
Return New ArrayList()
End Get
End Property
Public Function Action(ByVal ActionName As String, ByVal ActionParameters As String) As String Implements ISwitchV2.Action
Throw New ActionNotImplementedException("Action " & ActionName & " is not supported by this driver")
End Function
Public Sub CommandBlind(ByVal Command As String, Optional ByVal Raw As Boolean = False) Implements ISwitchV2.CommandBlind
CheckConnected("CommandBlind")
Dim webclient As New System.Net.WebClient, result As String
Dim webMutex As Mutex ' Very simple multithreading. Don't need anything complicated, since there's no serial comms w/ the RR4005i
webMutex = New Mutex(False, "RRMutex")
webMutex.WaitOne()
Try
result = webclient.DownloadString(Command)
Catch ex As Exception
TL.LogMessage("CommandBlind", "Error Sending Command " & Command & " : " & ex.Message)
Finally
webMutex.ReleaseMutex()
End Try
End Sub
Public Function CommandBool(ByVal Command As String, Optional ByVal Raw As Boolean = False) As Boolean _
Implements ISwitchV2.CommandBool
' Nothing we'll use returns a boolean, not implemented
Throw New MethodNotImplementedException("CommandBool")
End Function
Public Function CommandString(ByVal Command As String, Optional ByVal Raw As Boolean = False) As String _
Implements ISwitchV2.CommandString
CheckConnected("CommandString")
Dim document As New XmlDocument, reader As New XmlTextReader(Command)
Dim webMutex As Mutex ' Very simple multithreading. Don't need anything complicated, since there's no serial comms w/ the RR4005i
webMutex = New Mutex(False, "RRMutex")
webMutex.WaitOne()
Try
document.Load(reader)
Return document.InnerXml.ToString()
Catch ex As Exception
TL.LogMessage("CommandBool", "Error Sending Command " & Command & " : " & ex.Message)
Return ""
Finally
webMutex.ReleaseMutex()
End Try
End Function
Public Property Connected() As Boolean Implements ISwitchV2.Connected
Get
TL.LogMessage("Connected Get", IsConnected.ToString())
Return IsConnected
End Get
Set(value As Boolean)
TL.LogMessage("Connected Set", value.ToString())
If value = IsConnected Then
Return
End If
If value Then
'**********************************
' We should be able to handle both reading the port names and verifying connectivity in one step
' TODO : This presumes firmware 1.14 or later, should probably modify this to account for earlier devices
'**********************************
Dim webclient As New System.Net.WebClient, result As String, splitChar As String = vbCrLf, index As Integer
For i As Integer = 0 To NumUnits - 1
Try
result = webclient.DownloadString("http://" & RRIP(i) & "/settings.cgi")
If bFetchNames Then
Dim strAry() As String = result.Split(splitChar)
For Each line As String In strAry
line = Replace(line, vbLf, String.Empty)
If line.StartsWith("RAILSTR") Then
index = CInt(line.Substring(7, 1))
PortNames(index + (i * 5)) = line.Substring(9)
If index = 4 Then
Exit For
End If
End If
Next
End If
TL.LogMessage("Connected Set", "Connected to RIGRunner at " & RRIP(i))
connectedState = True
Catch ex As Exception
TL.LogMessage("Connected Set", "Error connecting to RigRunner at " & RRIP(i))
End Try
Next
Else
connectedState = False
WriteProfile() ' Persist device configuration values to the ASCOM Profile store
If NumUnits > 1 Then
TL.LogMessage("Connected Set", "Disconnected from RigRunners")
Else
TL.LogMessage("Connected Set", "Disconnected from RigRunner")
End If
End If
End Set
End Property
Public ReadOnly Property Description As String Implements ISwitchV2.Description
Get
' this pattern seems to be needed to allow a public property to return a private field
Dim d As String = driverDescription
TL.LogMessage("Description Get", d)
Return d
End Get
End Property
Public ReadOnly Property DriverInfo As String Implements ISwitchV2.DriverInfo
Get
Dim m_version As Version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version
Dim s_driverInfo As String = "ASCOM Switch Driver for West Mountain Radio's RIGRunner 4005i. Version: " + m_version.Major.ToString() + "." + m_version.Minor.ToString()
TL.LogMessage("DriverInfo Get", s_driverInfo)
Return s_driverInfo
End Get
End Property
Public ReadOnly Property DriverVersion() As String Implements ISwitchV2.DriverVersion
Get
' Get our own assembly and report its version number
TL.LogMessage("DriverVersion Get", Reflection.Assembly.GetExecutingAssembly.GetName.Version.ToString(2))
Return Reflection.Assembly.GetExecutingAssembly.GetName.Version.ToString(2)
End Get
End Property
Public ReadOnly Property InterfaceVersion() As Short Implements ISwitchV2.InterfaceVersion
Get
TL.LogMessage("InterfaceVersion Get", "2")
Return 2
End Get
End Property
Public ReadOnly Property Name As String Implements ISwitchV2.Name
Get
Dim s_name As String = "ASCOM RIGRunner 4005i Switch Driver"
TL.LogMessage("Name Get", s_name)
Return s_name
End Get
End Property
Public Sub Dispose() Implements ISwitchV2.Dispose
' Clean up the tracelogger and util objects
TL.Enabled = False
TL.Dispose()
TL = Nothing
utilities.Dispose()
utilities = Nothing
astroUtilities.Dispose()
astroUtilities = Nothing
End Sub
#End Region
#Region "ISwitchV2 Implementation"
''' <summary>
''' The number of switches managed by this driver
''' </summary>
Public ReadOnly Property MaxSwitch As Short Implements ISwitchV2.MaxSwitch
Get
TL.LogMessage("MaxSwitch Get", numSwitches.ToString())
Return numSwitches
End Get
End Property
''' <summary>
''' Return the name of switch n
''' </summary>
''' <param name="id">The switch number to return</param>
''' <returns>The name of the switch</returns>
Public Function GetSwitchName(id As Short) As String Implements ISwitchV2.GetSwitchName
Validate("GetSwitchName", id)
TL.LogMessage("GetSwitchName", String.Format("Switch id {0} : {1}", id, PortNames(id)))
Return PortNames(id)
End Function
''' <summary>
''' Sets a switch name to a specified value
''' </summary>
''' <param name="id">The number of the switch whose name is to be set</param>
''' <param name="name">The name of the switch</param>
Sub SetSwitchName(id As Short, name As String) Implements ISwitchV2.SetSwitchName
'Not implemented : not allowing client to set port names
TL.LogMessage("SetSwitchName", "Not Implemented")
Throw New ASCOM.MethodNotImplementedException("SetSwitchName")
End Sub
''' <summary>
''' Gets the description of the specified switch. This is to allow a fuller description of
''' the switch to be returned, for example for a tool tip.
''' </summary>
''' <param name="id">The number of the switch whose description is to be returned</param><returns></returns>
''' <exception cref="MethodNotImplementedException">If the method is not implemented</exception>
''' <exception cref="InvalidValueException">If id is outside the range 0 to MaxSwitch - 1</exception>
Public Function GetSwitchDescription(id As Short) As String Implements ISwitchV2.GetSwitchDescription
' Just returns the switch name
Validate("GetSwitchDescription", id)
TL.LogMessage("GetSwitchDescription", String.Format("Switch id {0} : {1}", id, PortNames(id)))
Return PortNames(id)
End Function
''' <summary>
''' Reports if the specified switch can be written to.
''' This is false if the switch cannot be written to, for example a limit switch or a sensor.
''' The default is true.
''' </summary>
''' <param name="id">The number of the switch whose write state is to be returned</param><returns>
''' <c>true</c> if the switch can be set, otherwise <c>false</c>.
''' </returns>
''' <exception cref="MethodNotImplementedException">If the method is not implemented</exception>
''' <exception cref="InvalidValueException">If id is outside the range 0 to MaxSwitch - 1</exception>
Public Function CanWrite(id As Short) As Boolean Implements ISwitchV2.CanWrite
' Always return true. All ports on the rigrunner can be turned on or off
Validate("CanWrite", id)
TL.LogMessage("CanWrite", String.Format("Switch id {0} : True", id))
Return True
End Function
#Region "boolean members"
''' <summary>
''' Return the state of switch n as a boolean
''' A multi-value switch must throw a MethodNotImplementedException.
''' </summary>
''' <param name="id">The switch number to return</param>
''' <returns>True or false</returns>
Function GetSwitch(id As Short) As Boolean Implements ISwitchV2.GetSwitch
Validate("GetSwitch", id, True)
Dim xmld As New XmlDocument, result As Boolean
xmld.LoadXml(CommandString("http://" & RRIP(id \ 5) & "/status.xml"))
result = convertInt(CInt(xmld.SelectSingleNode("/rr4005i/RAILENA" & (id Mod 5).ToString).InnerText))
TL.LogMessage("GetSwitch", String.Format("Switch id {0} : {1}", id, result.ToString))
Return result
End Function
''' <summary>
''' Sets a switch to the specified state, true or false.
''' If the switch cannot be set then throws a MethodNotImplementedException.
''' A multi-value switch must throw a MethodNotImplementedException.
''' </summary>
''' <param name="ID">The number of the switch to set</param>
''' <param name="State">The required switch state</param>
Sub SetSwitch(id As Short, state As Boolean) Implements ISwitchV2.SetSwitch
Validate("SetSwitch", id, True)
CommandBlind("http://" & RRIP(id \ 5) & "/index.htm?RAILENA" & (id Mod 5).ToString & "=" & convertBool(state))
TL.LogMessage("SetSwitch", String.Format("Switch id {0} : {1}", id, state.ToString))
End Sub
#End Region
#Region "Analogue members"
''' <summary>
''' returns the maximum analogue value for this switch
''' boolean switches must return 1.0
''' </summary>
''' <param name="id"></param>
''' <returns></returns>
Function MaxSwitchValue(id As Short) As Double Implements ISwitchV2.MaxSwitchValue
Validate("MaxSwitchValue", id)
TL.LogMessage("MaxSwitchValue", String.Format("Switch id {0} : 1.0", id))
Return 1.0 ' All RR4005i switches are boolean
End Function
''' <summary>
''' returns the minimum analogue value for this switch
''' boolean switches must return 0.0
''' </summary>
''' <param name="id"></param>
''' <returns></returns>
Function MinSwitchValue(id As Short) As Double Implements ISwitchV2.MinSwitchValue
Validate("MinSwitchValue", id)
TL.LogMessage("MinSwitchValue", String.Format("Switch id {0} : 0.0", id))
Return 0.0 ' All RR4005i switches are boolean
End Function
''' <summary>
''' returns the step size that this switch supports. This gives the difference between
''' successive values of the switch.
''' The number of values is ((MaxSwitchValue - MinSwitchValue) / SwitchStep) + 1
''' boolean switches must return 1.0, giving two states.
''' </summary>
''' <param name="id"></param>
''' <returns></returns>
Function SwitchStep(id As Short) As Double Implements ISwitchV2.SwitchStep
Validate("SwitchStep", id)
TL.LogMessage("SwitchStep", "1.0")
Return 1.0 ' All RR4005i switches are boolean
End Function
''' <summary>
''' returns the analogue switch value for switch id
''' boolean switches must throw a MethodNotImplementedException
''' </summary>
''' <param name="id"></param>
''' <returns></returns>
Function GetSwitchValue(id As Short) As Double Implements ISwitchV2.GetSwitchValue
Dim retVal As Double
Validate("GetSwitchValue", id)
If GetSwitch(id) Then
retVal = 1.0
Else
retVal = 0.0
End If
TL.LogMessage("GetSwitchValue", String.Format("Switch id {0} : {1}", id, retVal))
Return retVal
End Function
''' <summary>
''' set the analogue value for this switch.
''' If the switch cannot be set then throws a MethodNotImplementedException.
''' If the value is not between the maximum and minimum then throws an InvalidValueException
''' boolean switches must throw a MethodNotImplementedException
''' </summary>
''' <param name="id"></param>
''' <param name="value"></param>
Sub SetSwitchValue(id As Short, value As Double) Implements ISwitchV2.SetSwitchValue
Dim setVal As Boolean
Validate("SetSwitchValue", id)
If value < MinSwitchValue(id) Or value > MaxSwitchValue(id) Then
Throw New InvalidValueException("", value.ToString(), String.Format("{0} to {1}", MinSwitchValue(id), MaxSwitchValue(id)))
TL.LogMessage("SetSwitchValue", String.Format("InvalidValueException Switch id {0} : value {1}", id, value))
End If
If value < 0.5 Then
setVal = False
Else
setVal = True
End If
TL.LogMessage("SetSwitchValue", String.Format("Switch id {0} : value {1}, set {2}", id, value, setVal.ToString))
SetSwitch(id, setVal)
End Sub
#End Region
#End Region
#Region "Validation Functions"
''' <summary>
''' Checks that the switch id is in range and throws an InvalidValueException if it isn't
''' </summary>
''' <param name="message">The message.</param>
''' <param name="id">The id.</param>
Private Sub Validate(message As String, id As Short)
If (id < 0 Or id >= numSwitches) Then
TL.LogMessage(message, String.Format("Switch {0} does not exist", id))
Throw New ASCOM.InvalidValueException(message, id.ToString(), String.Format("0 to {0}", numSwitches - 1))
End If
End Sub
''' <summary>
''' Checks that the number of states for the switch is correct and throws a methodNotImplemented exception if not.
''' Boolean switches must have 2 states and multi-value switches more than 2.
''' </summary>
''' <param name="message"></param>
''' <param name="id"></param>
''' <param name="expectBoolean"></param>
Private Sub Validate(message As String, id As Short, expectBoolean As Boolean)
Validate(message, id)
Dim ns As Integer = (((MaxSwitchValue(id) - MinSwitchValue(id)) / SwitchStep(id)) + 1)
If (expectBoolean And ns <> 2) Or (Not expectBoolean And ns <= 2) Then
TL.LogMessage(message, String.Format("Switch {0} has the wrong number of states", id, ns))
Throw New MethodNotImplementedException(String.Format("{0}({1})", message, id))
End If
End Sub
''' <summary>
''' Checks that the switch id and value are in range and throws an
''' InvalidValueException if they are not.
''' </summary>
''' <param name="message">The message.</param>
''' <param name="id">The id.</param>
''' <param name="value">The value.</param>
Private Sub Validate(message As String, id As Short, value As Double)
Validate(message, id, False)
Dim min = MinSwitchValue(id)
Dim max = MaxSwitchValue(id)
If (value < min Or value > max) Then
TL.LogMessage(message, String.Format("Value {1} for Switch {0} is out of the allowed range {2} to {3}", id, value, min, max))
Throw New InvalidValueException(message, value.ToString(), String.Format("Switch({0}) range {1} to {2}", id, min, max))
End If
End Sub
#End Region
#Region "ASCOM Registration"
Private Shared Sub RegUnregASCOM(ByVal bRegister As Boolean)
Using P As New Profile() With {.DeviceType = "Switch"}
If bRegister Then
P.Register(driverID, driverDescription)
Else
P.Unregister(driverID)
End If
End Using
End Sub
<ComRegisterFunction()> _
Public Shared Sub RegisterASCOM(ByVal T As Type)
RegUnregASCOM(True)
End Sub
<ComUnregisterFunction()> _
Public Shared Sub UnregisterASCOM(ByVal T As Type)
RegUnregASCOM(False)
End Sub
#End Region
#Region "Private properties and methods"
''' <summary>
''' Returns true if there is a valid connection to the driver hardware
''' </summary>
Private ReadOnly Property IsConnected As Boolean
Get
' connectedState is set in the Connect method
Return connectedState
End Get
End Property
''' <summary>
''' Use this function to throw an exception if we aren't connected to the hardware
''' </summary>
''' <param name="message"></param>
Private Sub CheckConnected(ByVal message As String)
If Not IsConnected Then
Throw New NotConnectedException(message)
End If
End Sub
''' <summary>
''' Read the device configuration from the ASCOM Profile store
''' </summary>
Friend Sub ReadProfile()
Dim iUnit As Integer, iPort As Integer
Using driverProfile As New Profile()
driverProfile.DeviceType = "Switch"
traceState = Convert.ToBoolean(driverProfile.GetValue(driverID, traceStateProfileName, String.Empty, traceStateDefault))
NumUnits = driverProfile.GetValue(driverID, numberOfUnitsProfileName, String.Empty, numberOfUnitsDefault)
numSwitches = driverProfile.GetValue(driverID, maxSwitchesProfileName, String.Empty, maxSwitchesDefault)
bFetchNames = driverProfile.GetValue(driverID, fetchNamesProfileName, String.Empty, fetchNamesDefault)
For i As Integer = 0 To NumUnits - 1
RRIP(i) = driverProfile.GetValue(driverID, IPProfileName, i.ToString, IPDefault)
Next
For i As Integer = 0 To numSwitches - 1
iUnit = i \ 5 ' Calculate the unit number that would hold this port
iPort = i Mod 5 ' Calculate the port number on that unit
PortNames(i) = driverProfile.GetValue(driverID, portNamesProfileName, iUnit.ToString & "\" & iPort.ToString, portNameDefault(i))
Next
End Using
End Sub
''' <summary>
''' Write the device configuration to the ASCOM Profile store
''' </summary>
Friend Sub WriteProfile()
Dim iUnit As Integer, iPort As Integer
Using driverProfile As New Profile()
driverProfile.DeviceType = "Switch"
driverProfile.WriteValue(driverID, traceStateProfileName, traceState.ToString())
driverProfile.WriteValue(driverID, numberOfUnitsProfileName, NumUnits)
driverProfile.WriteValue(driverID, maxSwitchesProfileName, NumUnits * 5)
driverProfile.WriteValue(driverID, fetchNamesProfileName, bFetchNames.ToString)
For i As Integer = 0 To NumUnits - 1
driverProfile.WriteValue(driverID, IPProfileName, RRIP(i), i.ToString)
Next
For i As Integer = 0 To (NumUnits * 5) - 1
iUnit = i \ 5 ' Calculate the unit number that would hold this port
iPort = i Mod 5 ' Calculate the port number on that unit
driverProfile.WriteValue(driverID, portNamesProfileName, PortNames(i), iUnit.ToString & "\" & iPort.ToString)
Next
End Using
End Sub
#End Region
#Region "My Helper Functions"
' There are probably better ways to do these, but this is simple and readable and, well, I'm stupid and lazy, so here we are.
Friend Shared Function convertBool(value As Boolean) As Integer
If value Then
Return 1
Else
Return 0
End If
End Function
Friend Shared Function convertInt(value As Integer) As Boolean
If value = 1 Then
Return True
Else
Return False
End If
End Function
#End Region
End Class