Instrument Neutral Distributed Interface INDI 2.2.5
MapPropertiesToInMemoryDatabase.cpp
Go to the documentation of this file.
1
10
11#include <cfloat>
12
13namespace INDI
14{
15namespace 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
75void 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
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
256void 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
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
AlignmentDatabaseType & GetAlignmentDatabase()
Get a reference to the in memory database.
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
void registerProperty(const INDI::Property &property)
Register the property to be able to observe and update.
ISState
Switch state.
Definition indiapi.h:148
@ ISS_OFF
Definition indiapi.h:149
@ ISS_ON
Definition indiapi.h:150
#define MAXINDIBLOBFMT
Definition indiapi.h:194
@ IP_RW
Definition indiapi.h:184
@ IP_RO
Definition indiapi.h:182
@ IPS_ALERT
Definition indiapi.h:162
@ IPS_IDLE
Definition indiapi.h:159
@ IPS_OK
Definition indiapi.h:160
@ ISR_1OFMANY
Definition indiapi.h:171
@ ISR_ATMOST1
Definition indiapi.h:172
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:490
void IUResetSwitch(ISwitchVectorProperty *svp)
Reset all switches in a switch vector property to OFF.
Definition indidevapi.c:366
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:376
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:398
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:453
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:528
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:434
#define INDI_UNUSED(x)
Definition indidevapi.h:132
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.
int IUUpdateSwitch(ISwitchVectorProperty *svp, ISState *states, char *names[], int n)
Update all switches in a switch vector property.
void IDSetNumber(const INumberVectorProperty *nvp, const char *fmt,...)
void IDSetSwitch(const ISwitchVectorProperty *svp, const char *fmt,...)
int IUUpdateNumber(INumberVectorProperty *nvp, double values[], char *names[], int n)
Update all numbers in a number vector property.
void IDSetBLOB(const IBLOBVectorProperty *bvp, const char *fmt,...)
#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:469
char name[MAXINDINAME]
Definition indiapi.h:473
char name[MAXINDINAME]
Definition indiapi.h:321
char name[MAXINDINAME]
Definition indiapi.h:369