Instrument Neutral Distributed Interface INDI  2.0.2
MapPropertiesToInMemoryDatabase.cpp
Go to the documentation of this file.
1 
10 
11 #include <cfloat>
12 
13 namespace INDI
14 {
15 namespace AlignmentSubsystem
16 {
18 {
19  IUFillNumber(&AlignmentPointSetEntry[ENTRY_OBSERVATION_JULIAN_DATE],
20  "ALIGNMENT_POINT_ENTRY_OBSERVATION_JULIAN_DATE", "Observation Julian date", "%g", 0, 60000, 0, 0);
21  IUFillNumber(&AlignmentPointSetEntry[ENTRY_RA], "ALIGNMENT_POINT_ENTRY_RA", "Right Ascension (hh:mm:ss)", "%010.6m",
22  0, 24, 0, 0);
23  IUFillNumber(&AlignmentPointSetEntry[ENTRY_DEC], "ALIGNMENT_POINT_ENTRY_DEC", "Declination (dd:mm:ss)", "%010.6m",
24  -90, 90, 0, 0);
25  IUFillNumber(&AlignmentPointSetEntry[ENTRY_VECTOR_X], "ALIGNMENT_POINT_ENTRY_VECTOR_X",
26  "Telescope direction vector x", "%g", -FLT_MAX, FLT_MAX, 0, 0);
27  IUFillNumber(&AlignmentPointSetEntry[ENTRY_VECTOR_Y], "ALIGNMENT_POINT_ENTRY_VECTOR_Y",
28  "Telescope direction vector y", "%g", -FLT_MAX, FLT_MAX, 0, 0);
29  IUFillNumber(&AlignmentPointSetEntry[ENTRY_VECTOR_Z], "ALIGNMENT_POINT_ENTRY_VECTOR_Z",
30  "Telescope direction vector z", "%g", -FLT_MAX, FLT_MAX, 0, 0);
31  IUFillNumberVector(&AlignmentPointSetEntryV, AlignmentPointSetEntry, 6, pTelescope->getDeviceName(),
32  "ALIGNMENT_POINT_MANDATORY_NUMBERS", "Mandatory sync point numeric fields", ALIGNMENT_TAB, IP_RW,
33  60, IPS_IDLE);
34  pTelescope->registerProperty(&AlignmentPointSetEntryV);
35 
36  IUFillBLOB(&AlignmentPointSetPrivateBinaryData, "ALIGNMENT_POINT_ENTRY_PRIVATE", "Private binary data",
37  "alignmentPrivateData");
38  IUFillBLOBVector(&AlignmentPointSetPrivateBinaryDataV, &AlignmentPointSetPrivateBinaryData, 1,
39  pTelescope->getDeviceName(), "ALIGNMENT_POINT_OPTIONAL_BINARY_BLOB",
40  "Optional sync point binary data", ALIGNMENT_TAB, IP_RW, 60, IPS_IDLE);
41  pTelescope->registerProperty(&AlignmentPointSetPrivateBinaryDataV);
42 
43  IUFillNumber(&AlignmentPointSetSize, "ALIGNMENT_POINTSET_SIZE", "Size", "%g", 0, 100000, 0, 0);
44  IUFillNumberVector(&AlignmentPointSetSizeV, &AlignmentPointSetSize, 1, pTelescope->getDeviceName(),
45  "ALIGNMENT_POINTSET_SIZE", "Current Set", ALIGNMENT_TAB, IP_RO, 60, IPS_IDLE);
46  pTelescope->registerProperty(&AlignmentPointSetSizeV);
47 
48  IUFillNumber(&AlignmentPointSetPointer, "ALIGNMENT_POINTSET_CURRENT_ENTRY", "Pointer", "%g", 0, 100000, 0, 0);
49  IUFillNumberVector(&AlignmentPointSetPointerV, &AlignmentPointSetPointer, 1, pTelescope->getDeviceName(),
50  "ALIGNMENT_POINTSET_CURRENT_ENTRY", "Current Set", ALIGNMENT_TAB, IP_RW, 60, IPS_IDLE);
51  pTelescope->registerProperty(&AlignmentPointSetPointerV);
52 
53  IUFillSwitch(&AlignmentPointSetAction[0], "APPEND", "Add entries at end of set", ISS_ON);
54  IUFillSwitch(&AlignmentPointSetAction[1], "INSERT", "Insert entries at current index", ISS_OFF);
55  IUFillSwitch(&AlignmentPointSetAction[2], "EDIT", "Overwrite entry at current index", ISS_OFF);
56  IUFillSwitch(&AlignmentPointSetAction[3], "DELETE", "Delete entry at current index", ISS_OFF);
57  IUFillSwitch(&AlignmentPointSetAction[4], "CLEAR", "Delete all the entries in the set", ISS_OFF);
58  IUFillSwitch(&AlignmentPointSetAction[5], "READ", "Read the entry at the current pointer", ISS_OFF);
59  IUFillSwitch(&AlignmentPointSetAction[6], "READ INCREMENT", "Increment the pointer before reading the entry",
60  ISS_OFF);
61  IUFillSwitch(&AlignmentPointSetAction[7], "LOAD DATABASE", "Load the alignment database from local storage",
62  ISS_OFF);
63  IUFillSwitch(&AlignmentPointSetAction[8], "SAVE DATABASE", "Save the alignment database to local storage", ISS_OFF);
64  IUFillSwitchVector(&AlignmentPointSetActionV, AlignmentPointSetAction, 9, pTelescope->getDeviceName(),
65  "ALIGNMENT_POINTSET_ACTION", "Action to take", ALIGNMENT_TAB, IP_RW, ISR_1OFMANY, 60, IPS_IDLE);
66  pTelescope->registerProperty(&AlignmentPointSetActionV);
67 
68  IUFillSwitch(&AlignmentPointSetCommit, "ALIGNMENT_POINTSET_COMMIT", "OK", ISS_OFF);
69  IUFillSwitchVector(&AlignmentPointSetCommitV, &AlignmentPointSetCommit, 1, pTelescope->getDeviceName(),
70  "ALIGNMENT_POINTSET_COMMIT", "Execute the action", ALIGNMENT_TAB, IP_RW, ISR_ATMOST1, 60,
71  IPS_IDLE);
72  pTelescope->registerProperty(&AlignmentPointSetCommitV);
73 }
74 
75 void MapPropertiesToInMemoryDatabase::ProcessBlobProperties(Telescope *pTelescope, const char *name, int sizes[],
76  int blobsizes[], char *blobs[], char *formats[],
77  char *names[], int n)
78 {
79  DEBUGFDEVICE(pTelescope->getDeviceName(), INDI::Logger::DBG_DEBUG, "ProcessBlobProperties - name(%s)", name);
80  if (strcmp(name, AlignmentPointSetPrivateBinaryDataV.name) == 0)
81  {
82  AlignmentPointSetPrivateBinaryDataV.s = IPS_OK;
83  if (0 == IUUpdateBLOB(&AlignmentPointSetPrivateBinaryDataV, sizes, blobsizes, blobs, formats, names, n))
84  {
85  // Reset the blob format string just in case it got trashed
86  strncpy(AlignmentPointSetPrivateBinaryData.format, "alignmentPrivateData", MAXINDIBLOBFMT);
87 
88  // Send back a dummy zero length blob
89  // to inform client I have received the data
90  IBLOB DummyBlob;
91  IBLOBVectorProperty DummyBlobV;
92  IUFillBLOB(&DummyBlob, "ALIGNMENT_POINT_ENTRY_PRIVATE", "Private binary data", "alignmentPrivateData");
93  IUFillBLOBVector(&DummyBlobV, &DummyBlob, 1, pTelescope->getDeviceName(),
94  "ALIGNMENT_POINT_OPTIONAL_BINARY_BLOB", "Optional sync point binary data", ALIGNMENT_TAB,
95  IP_RW, 60, IPS_OK);
96  IDSetBLOB(&DummyBlobV, nullptr);
97  }
98  }
99 }
100 
101 void MapPropertiesToInMemoryDatabase::ProcessNumberProperties(Telescope *, const char *name, double values[],
102  char *names[], int n)
103 {
104  //DEBUGFDEVICE(pTelescope->getDeviceName(), INDI::Logger::DBG_DEBUG, "ProcessNumberProperties - name(%s)", name);
105  if (strcmp(name, AlignmentPointSetEntryV.name) == 0)
106  {
107  AlignmentPointSetEntryV.s = IPS_OK;
108  if (0 == IUUpdateNumber(&AlignmentPointSetEntryV, values, names, n))
109  // Update client
110  IDSetNumber(&AlignmentPointSetEntryV, nullptr);
111  }
112  else if (strcmp(name, AlignmentPointSetPointerV.name) == 0)
113  {
114  AlignmentPointSetPointerV.s = IPS_OK;
115  if (0 == IUUpdateNumber(&AlignmentPointSetPointerV, values, names, n))
116  // Update client
117  IDSetNumber(&AlignmentPointSetPointerV, nullptr);
118  }
119 }
120 
122  char *names[], int n)
123 {
124  //DEBUGFDEVICE(pTelescope->getDeviceName(), INDI::Logger::DBG_DEBUG, "ProcessSwitchProperties - name(%s)", name);
125  AlignmentDatabaseType &AlignmentDatabase = GetAlignmentDatabase();
126  if (strcmp(name, AlignmentPointSetActionV.name) == 0)
127  {
128  AlignmentPointSetActionV.s = IPS_OK;
129  if (0 == IUUpdateSwitch(&AlignmentPointSetActionV, states, names, n))
130  // Update client
131  IDSetSwitch(&AlignmentPointSetActionV, nullptr);
132  }
133  else if (strcmp(name, AlignmentPointSetCommitV.name) == 0)
134  {
135  const unsigned int Offset = AlignmentPointSetPointer.value;
136  AlignmentPointSetCommitV.s = IPS_OK;
137 
138  // Perform the database action
139  AlignmentDatabaseEntry CurrentValues;
140  CurrentValues.ObservationJulianDate = AlignmentPointSetEntry[ENTRY_OBSERVATION_JULIAN_DATE].value;
141  CurrentValues.RightAscension = AlignmentPointSetEntry[ENTRY_RA].value;
142  CurrentValues.Declination = AlignmentPointSetEntry[ENTRY_DEC].value;
143  CurrentValues.TelescopeDirection.x = AlignmentPointSetEntry[ENTRY_VECTOR_X].value;
144  CurrentValues.TelescopeDirection.y = AlignmentPointSetEntry[ENTRY_VECTOR_Y].value;
145  CurrentValues.TelescopeDirection.z = AlignmentPointSetEntry[ENTRY_VECTOR_Z].value;
146  if ((0 != AlignmentPointSetPrivateBinaryData.size) && (nullptr != AlignmentPointSetPrivateBinaryData.blob))
147  {
148  CurrentValues.PrivateData.reset(new unsigned char[AlignmentPointSetPrivateBinaryData.size]);
149  memcpy(CurrentValues.PrivateData.get(), AlignmentPointSetPrivateBinaryData.blob,
150  AlignmentPointSetPrivateBinaryData.size);
151  CurrentValues.PrivateDataSize = AlignmentPointSetPrivateBinaryData.size;
152  }
153 
154  if (AlignmentPointSetAction[APPEND].s == ISS_ON)
155  {
156  AlignmentDatabase.push_back(CurrentValues);
157  AlignmentPointSetSize.value = AlignmentDatabase.size();
158  // Update client
159  IDSetNumber(&AlignmentPointSetSizeV, nullptr);
160  }
161  else if (AlignmentPointSetAction[INSERT].s == ISS_ON)
162  {
163  if (Offset > AlignmentDatabase.size())
164  AlignmentPointSetCommitV.s = IPS_ALERT;
165  else
166  {
167  AlignmentDatabase.insert(AlignmentDatabase.begin() + Offset, CurrentValues);
168  AlignmentPointSetSize.value = AlignmentDatabase.size();
169  // Update client
170  IDSetNumber(&AlignmentPointSetSizeV, nullptr);
171  }
172  }
173  else if (AlignmentPointSetAction[EDIT].s == ISS_ON)
174  {
175  if (Offset >= AlignmentDatabase.size())
176  AlignmentPointSetCommitV.s = IPS_ALERT;
177  else
178  AlignmentDatabase[Offset] = CurrentValues;
179  }
180  else if (AlignmentPointSetAction[DELETE].s == ISS_ON)
181  {
182  if (Offset >= AlignmentDatabase.size())
183  AlignmentPointSetCommitV.s = IPS_ALERT;
184  else
185  {
186  AlignmentDatabase.erase(AlignmentDatabase.begin() + Offset);
187  AlignmentPointSetSize.value = AlignmentDatabase.size();
188  // Update client
189  IDSetNumber(&AlignmentPointSetSizeV, nullptr);
190  }
191  }
192  else if (AlignmentPointSetAction[CLEAR].s == ISS_ON)
193  {
194  // AlignmentDatabaseType().swap(AlignmentDatabase); // Do it this wasy to force a reallocation
195  AlignmentDatabase.clear();
196  AlignmentPointSetSize.value = 0;
197  // Update client
198  IDSetNumber(&AlignmentPointSetSizeV, nullptr);
199  }
200  else if ((AlignmentPointSetAction[READ].s == ISS_ON) || (AlignmentPointSetAction[READ_INCREMENT].s == ISS_ON))
201  {
202  if (AlignmentPointSetAction[READ_INCREMENT].s == ISS_ON)
203  {
204  AlignmentPointSetPointer.value++;
205  // Update client
206  IDSetNumber(&AlignmentPointSetPointerV, nullptr);
207  }
208 
209  if (Offset >= AlignmentDatabase.size())
210  AlignmentPointSetCommitV.s = IPS_ALERT;
211  else
212  {
213  AlignmentPointSetEntry[ENTRY_OBSERVATION_JULIAN_DATE].value =
214  AlignmentDatabase[Offset].ObservationJulianDate;
215  AlignmentPointSetEntry[ENTRY_RA].value = AlignmentDatabase[Offset].RightAscension;
216  AlignmentPointSetEntry[ENTRY_DEC].value = AlignmentDatabase[Offset].Declination;
217  AlignmentPointSetEntry[ENTRY_VECTOR_X].value = AlignmentDatabase[Offset].TelescopeDirection.x;
218  AlignmentPointSetEntry[ENTRY_VECTOR_Y].value = AlignmentDatabase[Offset].TelescopeDirection.y;
219  AlignmentPointSetEntry[ENTRY_VECTOR_Z].value = AlignmentDatabase[Offset].TelescopeDirection.z;
220 
221  // Update client
222  IDSetNumber(&AlignmentPointSetEntryV, nullptr);
223 
224  if ((0 != AlignmentDatabase[Offset].PrivateDataSize) &&
225  (nullptr != AlignmentDatabase[Offset].PrivateData.get()))
226  {
227  // Hope that INDI has freed the old pointer !!!!!!!!!!!
228  AlignmentPointSetPrivateBinaryData.blob = malloc(AlignmentDatabase[Offset].PrivateDataSize);
229  memcpy(AlignmentPointSetPrivateBinaryData.blob, AlignmentDatabase[Offset].PrivateData.get(),
230  AlignmentDatabase[Offset].PrivateDataSize);
231  AlignmentPointSetPrivateBinaryData.bloblen = AlignmentDatabase[Offset].PrivateDataSize;
232  AlignmentPointSetPrivateBinaryData.size = AlignmentDatabase[Offset].PrivateDataSize;
233  AlignmentPointSetPrivateBinaryDataV.s = IPS_OK;
234  IDSetBLOB(&AlignmentPointSetPrivateBinaryDataV, nullptr);
235  }
236  }
237  }
238  else if (AlignmentPointSetAction[LOAD_DATABASE].s == ISS_ON)
239  {
240  LoadDatabase(pTelescope->getDeviceName());
241  AlignmentPointSetSize.value = AlignmentDatabase.size();
242  // Update client
243  IDSetNumber(&AlignmentPointSetSizeV, nullptr);
244  }
245  else if (AlignmentPointSetAction[SAVE_DATABASE].s == ISS_ON)
246  {
247  SaveDatabase(pTelescope->getDeviceName());
248  }
249 
250  // Update client
251  IUResetSwitch(&AlignmentPointSetCommitV);
252  IDSetSwitch(&AlignmentPointSetCommitV, nullptr);
253  }
254 }
255 
256 void MapPropertiesToInMemoryDatabase::UpdateLocation(double latitude, double longitude, double elevation)
257 {
258  INDI_UNUSED(elevation);
259  IGeographicCoordinates Position { 0, 0, 0 };
260 
261  if (GetDatabaseReferencePosition(Position))
262  {
263  // Position is already valid
264  if ((latitude != Position.latitude) || (longitude != Position.longitude))
265  {
266  // Warn the user somehow
267  }
268  }
269  else
270  SetDatabaseReferencePosition(latitude, longitude);
271 }
272 
274 {
275  AlignmentPointSetSize.value = GetAlignmentDatabase().size();
276  // Update client
277  IDSetNumber(&AlignmentPointSetSizeV, nullptr);
278 }
279 
280 } // namespace AlignmentSubsystem
281 } // namespace INDI
AlignmentDatabaseType & GetAlignmentDatabase()
Get a reference to the in memory database.
bool SaveDatabase(const char *DeviceName)
Save the database to persistent storage.
void SetDatabaseReferencePosition(double Latitude, double Longitude)
Set the database reference position.
std::vector< AlignmentDatabaseEntry > AlignmentDatabaseType
bool GetDatabaseReferencePosition(IGeographicCoordinates &Position)
Get the database reference position.
bool LoadDatabase(const char *DeviceName)
Load the database from persistent storage.
void ProcessNumberProperties(Telescope *, const char *name, double values[], char *names[], int n)
Call this function from within the ISNewNumber processing path. The function will handle any alignmen...
void InitProperties(Telescope *pTelescope)
Initialize alignment database properties. It is recommended to call this function within initProperti...
void UpdateLocation(double latitude, double longitude, double elevation)
Call this function from within the updateLocation processing path.
void UpdateSize()
Call this function when the number of entries in the database changes.
void ProcessBlobProperties(Telescope *pTelescope, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n)
Call this function from within the ISNewBLOB processing path. The function will handle any alignment ...
void ProcessSwitchProperties(Telescope *pTelescope, const char *name, ISState *states, char *names[], int n)
Call this function from within the ISNewSwitch processing path. The function will handle any alignmen...
const char * getDeviceName() const
Definition: basedevice.cpp:821
void registerProperty(const INDI::Property &property)
Register the property to be able to observe and update.
Definition: basedevice.cpp:924
ISState
Switch state.
Definition: indiapi.h:150
@ ISS_OFF
Definition: indiapi.h:151
@ ISS_ON
Definition: indiapi.h:152
#define MAXINDIBLOBFMT
Definition: indiapi.h:196
@ IP_RW
Definition: indiapi.h:186
@ IP_RO
Definition: indiapi.h:184
@ IPS_ALERT
Definition: indiapi.h:164
@ IPS_IDLE
Definition: indiapi.h:161
@ IPS_OK
Definition: indiapi.h:162
@ ISR_1OFMANY
Definition: indiapi.h:173
@ ISR_ATMOST1
Definition: indiapi.h:174
void IUFillNumberVector(INumberVectorProperty *nvp, INumber *np, int nnp, const char *dev, const char *name, const char *label, const char *group, IPerm p, double timeout, IPState s)
Assign attributes for a number vector property. The vector's auxiliary elements will be set to NULL.
Definition: indidevapi.c:272
void IUResetSwitch(ISwitchVectorProperty *svp)
Reset all switches in a switch vector property to OFF.
Definition: indidevapi.c:148
void IUFillSwitch(ISwitch *sp, const char *name, const char *label, ISState s)
Assign attributes for a switch property. The switch's auxiliary elements will be set to NULL.
Definition: indidevapi.c:158
void IUFillNumber(INumber *np, const char *name, const char *label, const char *format, double min, double max, double step, double value)
Assign attributes for a number property. The number's auxiliary elements will be set to NULL.
Definition: indidevapi.c:180
void IUFillSwitchVector(ISwitchVectorProperty *svp, ISwitch *sp, int nsp, const char *dev, const char *name, const char *label, const char *group, IPerm p, ISRule r, double timeout, IPState s)
Assign attributes for a switch vector property. The vector's auxiliary elements will be set to NULL.
Definition: indidevapi.c:235
void IUFillBLOBVector(IBLOBVectorProperty *bvp, IBLOB *bp, int nbp, const char *dev, const char *name, const char *label, const char *group, IPerm p, double timeout, IPState s)
Assign attributes for a BLOB vector property. The vector's auxiliary elements will be set to NULL.
Definition: indidevapi.c:310
void IUFillBLOB(IBLOB *bp, const char *name, const char *label, const char *format)
Assign attributes for a BLOB property. The BLOB's data and auxiliary elements will be set to NULL.
Definition: indidevapi.c:216
#define INDI_UNUSED(x)
Definition: indidevapi.h:131
int IUUpdateBLOB(IBLOBVectorProperty *bvp, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n)
Update all BLOB members in a BLOB vector property.
Definition: indidriver.c:1422
int IUUpdateSwitch(ISwitchVectorProperty *svp, ISState *states, char *names[], int n)
Update all switches in a switch vector property.
Definition: indidriver.c:1308
void IDSetNumber(const INumberVectorProperty *nvp, const char *fmt,...)
Definition: indidriver.c:1211
void IDSetSwitch(const ISwitchVectorProperty *svp, const char *fmt,...)
Definition: indidriver.c:1231
int IUUpdateNumber(INumberVectorProperty *nvp, double values[], char *names[], int n)
Update all numbers in a number vector property.
Definition: indidriver.c:1362
void IDSetBLOB(const IBLOBVectorProperty *bvp, const char *fmt,...)
Definition: indidriver.c:1287
#define DEBUGFDEVICE(device, priority, msg,...)
Definition: indilogger.h:61
#define ALIGNMENT_TAB
Namespace to encapsulate INDI client, drivers, and mediator classes.
One Blob (Binary Large Object) descriptor.
Entry in the in memory alignment database.
Definition: Common.h:152
double RightAscension
Right ascension in decimal hours. N.B. libnova works in decimal degrees so conversion is always neede...
Definition: Common.h:190
TelescopeDirectionVector TelescopeDirection
Normalised vector giving telescope pointing direction. This is referred to elsewhere as the "apparent...
Definition: Common.h:197
double Declination
Declination in decimal degrees.
Definition: Common.h:193
int PrivateDataSize
This size in bytes of any private data.
Definition: Common.h:203
std::unique_ptr< unsigned char > PrivateData
Private data associated with this sync point.
Definition: Common.h:200
BLOB (Binary Large Object) vector property descriptor.
Definition: indiapi.h:471
char name[MAXINDINAME]
Definition: indiapi.h:475
char name[MAXINDINAME]
Definition: indiapi.h:323
char name[MAXINDINAME]
Definition: indiapi.h:371