Instrument Neutral Distributed Interface INDI  1.9.2
agent_imager.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2  Copyright(c) 2013-2016 CloudMakers, s. r. o. All rights reserved.
3  Copyright(c) 2017 Marco Gulino <marco.gulino@gmai.com>
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Library General Public
7  License version 2 as published by the Free Software Foundation.
8 
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  Library General Public License for more details.
13 
14  You should have received a copy of the GNU Library General Public License
15  along with this library; see the file COPYING.LIB. If not, write to
16  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  Boston, MA 02110-1301, USA.
18  *******************************************************************************/
19 
20 #include "agent_imager.h"
21 #include "indistandardproperty.h"
22 
23 #include <cstring>
24 #include <algorithm>
25 #include <memory>
26 
27 #include "group.h"
28 
29 #define DOWNLOAD_TAB "Download images"
30 #define IMAGE_NAME "%s/%s_%d_%03d%s"
31 #define IMAGE_PREFIX "_TMP_"
32 
33 
34 #define GROUP_PREFIX "GROUP_"
35 #define GROUP_PREFIX_LEN 6
36 
37 
38 const std::string Imager::DEVICE_NAME = "Imager Agent";
39 std::shared_ptr<Imager> imager(new Imager());
40 
41 // Imager ----------------------------------------------------------------------------
42 
44 {
45  setVersion(1, 2);
46  groups.resize(MAX_GROUP_COUNT);
47  int i=0;
48  std::generate(groups.begin(), groups.end(), [this, &i] { return std::make_shared<Group>(i++, this); });
49 }
50 
51 bool Imager::isRunning()
52 {
53  return ProgressNP.s == IPS_BUSY;
54 }
55 
56 bool Imager::isCCDConnected()
57 {
58  return StatusL[0].s == IPS_OK;
59 }
60 
61 bool Imager::isFilterConnected()
62 {
63  return StatusL[1].s == IPS_OK;
64 }
65 
66 std::shared_ptr<Group> Imager::getGroup(int index) const {
67  if(index > -1 && index <= maxGroup)
68  return groups[index];
69  return {};
70 }
71 
72 std::shared_ptr<Group> Imager::currentGroup() const {
73  return getGroup(group - 1);
74 }
75 
76 
77 
78 std::shared_ptr<Group> Imager::nextGroup() const {
79  return getGroup(group);
80 }
81 
82 void Imager::initiateNextFilter()
83 {
84  if (!isRunning())
85  return;
86 
87  if (group > 0 && image > 0 && group <= maxGroup && image <= maxImage)
88  {
89  int filterSlot = currentGroup()->filterSlot();
90 
91  if (!isFilterConnected())
92  {
93  if (filterSlot != 0)
94  {
95  ProgressNP.s = IPS_ALERT;
96  IDSetNumber(&ProgressNP, "Filter wheel is not connected");
97  return;
98  }
99  else
100  {
101  initiateNextCapture();
102  }
103  }
104  else if (filterSlot != 0 && FilterSlotN[0].value != filterSlot)
105  {
106  FilterSlotN[0].value = filterSlot;
107  sendNewNumber(&FilterSlotNP);
108  LOGF_DEBUG("Group %d of %d, image %d of %d, filer %d, filter set initiated on %s",
109  group, maxGroup, image, maxImage, (int)FilterSlotN[0].value, FilterSlotNP.device);
110  }
111  else
112  {
113  initiateNextCapture();
114  }
115  }
116 }
117 
118 void Imager::initiateNextCapture()
119 {
120  if (isRunning())
121  {
122  if (group > 0 && image > 0 && group <= maxGroup && image <= maxImage)
123  {
124  if (!isCCDConnected())
125  {
126  ProgressNP.s = IPS_ALERT;
127  IDSetNumber(&ProgressNP, "CCD is not connected");
128  return;
129  }
130  CCDImageBinN[0].value = currentGroup()->binning();
131  CCDImageBinN[1].value = currentGroup()->binning();
132  sendNewNumber(&CCDImageBinNP);
133  CCDImageExposureN[0].value = currentGroup()->exposure();
134  sendNewNumber(&CCDImageExposureNP);
135  IUSaveText(&CCDUploadSettingsT[0], ImageNameT[0].text);
136  IUSaveText(&CCDUploadSettingsT[1], "_TMP_");
137  sendNewSwitch(&CCDUploadSP);
138  sendNewText(&CCDUploadSettingsTP);
139  LOGF_DEBUG("Group %d of %d, image %d of %d, duration %.1fs, binning %d, capture initiated on %s", group,
140  maxGroup, image, maxImage, CCDImageExposureN[0].value, (int)CCDImageBinN[0].value,
141  CCDImageExposureNP.device);
142  }
143  }
144 }
145 
146 void Imager::startBatch()
147 {
148  LOG_DEBUG("Batch started");
149  ProgressN[0].value = group = 1;
150  ProgressN[1].value = image = 1;
151  maxImage = currentGroup()->count();
152  ProgressNP.s = IPS_BUSY;
153  IDSetNumber(&ProgressNP, nullptr);
154  initiateNextFilter();
155 }
156 
157 void Imager::abortBatch()
158 {
159  ProgressNP.s = IPS_ALERT;
160  IDSetNumber(&ProgressNP, "Batch aborted");
161 }
162 
163 void Imager::batchDone()
164 {
165  ProgressNP.s = IPS_OK;
166  IDSetNumber(&ProgressNP, "Batch done");
167 }
168 
169 void Imager::initiateDownload()
170 {
171  int group = (int)DownloadN[0].value;
172  int image = (int)DownloadN[1].value;
173  char name[128]={0};
174  std::ifstream file;
175 
176  if (group == 0 || image == 0)
177  return;
178 
179  sprintf(name, IMAGE_NAME, ImageNameT[0].text, ImageNameT[1].text, group, image, format);
180  file.open(name, std::ios::in | std::ios::binary | std::ios::ate);
181  DownloadN[0].value = 0;
182  DownloadN[1].value = 0;
183  if (file.is_open())
184  {
185  long size = file.tellg();
186  char *data = new char[size];
187 
188  file.seekg(0, std::ios::beg);
189  file.read(data, size);
190  file.close();
191  remove(name);
192  LOGF_DEBUG("Group %d, image %d, download initiated", group, image);
193  DownloadNP.s = IPS_BUSY;
194  IDSetNumber(&DownloadNP, "Download initiated");
195  strncpy(FitsB[0].format, format, MAXINDIBLOBFMT);
196  FitsB[0].blob = data;
197  FitsB[0].bloblen = FitsB[0].size = size;
198  FitsBP.s = IPS_OK;
199  IDSetBLOB(&FitsBP, nullptr);
200  DownloadNP.s = IPS_OK;
201  IDSetNumber(&DownloadNP, "Download finished");
202  }
203  else
204  {
205  DownloadNP.s = IPS_ALERT;
206  IDSetNumber(&DownloadNP, "Download failed");
207  LOGF_DEBUG("Group %d, image %d, upload failed", group, image);
208  }
209 }
210 
211 // DefaultDevice ----------------------------------------------------------------------------
212 
214 {
215  return Imager::DEVICE_NAME.c_str();
216 }
217 
219 {
221 
222  addDebugControl();
223 
224  IUFillNumber(&GroupCountN[0], "GROUP_COUNT", "Image group count", "%3.0f", 1, MAX_GROUP_COUNT, 1, maxGroup = 1);
225  IUFillNumberVector(&GroupCountNP, GroupCountN, 1, getDefaultName(), "GROUPS", "Image groups", MAIN_CONTROL_TAB, IP_RW,
226  60, IPS_IDLE);
227 
228  IUFillText(&ControlledDeviceT[0], "CCD", "CCD", "CCD Simulator");
229  IUFillText(&ControlledDeviceT[1], "FILTER", "Filter wheel", "Filter Simulator");
230  IUFillTextVector(&ControlledDeviceTP, ControlledDeviceT, 2, getDefaultName(), "DEVICES", "Controlled devices",
232  controlledCCD = ControlledDeviceT[0].text;
233  controlledFilterWheel = ControlledDeviceT[1].text;
234 
235  IUFillLight(&StatusL[0], "CCD", controlledCCD, IPS_IDLE);
236  IUFillLight(&StatusL[1], "FILTER", controlledFilterWheel, IPS_IDLE);
237  IUFillLightVector(&StatusLP, StatusL, 2, getDefaultName(), "STATUS", "Controlled devices", MAIN_CONTROL_TAB, IPS_IDLE);
238 
239  IUFillNumber(&ProgressN[0], "GROUP", "Current group", "%3.0f", 1, MAX_GROUP_COUNT, 1, 0);
240  IUFillNumber(&ProgressN[1], "IMAGE", "Current image", "%3.0f", 1, 100, 1, 0);
241  IUFillNumber(&ProgressN[2], "REMAINING_TIME", "Remaining time", "%5.2f", 0, 36000, 0, 0.0);
242  IUFillNumberVector(&ProgressNP, ProgressN, 3, getDefaultName(), "PROGRESS", "Batch execution progress", MAIN_CONTROL_TAB,
243  IP_RO, 60, IPS_IDLE);
244 
245  IUFillSwitch(&BatchS[0], "START", "Start batch", ISS_OFF);
246  IUFillSwitch(&BatchS[1], "ABORT", "Abort batch", ISS_OFF);
247  IUFillSwitchVector(&BatchSP, BatchS, 2, getDefaultName(), "BATCH", "Batch control", MAIN_CONTROL_TAB, IP_RW, ISR_NOFMANY,
248  60, IPS_IDLE);
249 
250  IUFillText(&ImageNameT[0], "IMAGE_FOLDER", "Image folder", "/tmp");
251  IUFillText(&ImageNameT[1], "IMAGE_PREFIX", "Image prefix", "IMG");
252  IUFillTextVector(&ImageNameTP, ImageNameT, 2, getDefaultName(), "IMAGE_NAME", "Image name", OPTIONS_TAB, IP_RW, 60,
253  IPS_IDLE);
254 
255  IUFillNumber(&DownloadN[0], "GROUP", "Group", "%3.0f", 1, MAX_GROUP_COUNT, 1, 1);
256  IUFillNumber(&DownloadN[1], "IMAGE", "Image", "%3.0f", 1, 100, 1, 1);
257  IUFillNumberVector(&DownloadNP, DownloadN, 2, getDefaultName(), "DOWNLOAD", "Download image", DOWNLOAD_TAB, IP_RW, 60,
258  IPS_IDLE);
259 
260  IUFillBLOB(&FitsB[0], "IMAGE", "Image", "");
261  IUFillBLOBVector(&FitsBP, FitsB, 1, getDefaultName(), "IMAGE", "Image Data", DOWNLOAD_TAB, IP_RO, 60, IPS_IDLE);
262 
263  defineProperty(&GroupCountNP);
264  defineProperty(&ControlledDeviceTP);
265  defineProperty(&ImageNameTP);
266 
267  for (int i = 0; i < GroupCountN[0].value; i++)
268  {
269  groups[i]->defineProperties();
270  }
271 
272  IUFillNumber(&CCDImageExposureN[0], "CCD_EXPOSURE_VALUE", "Duration (s)", "%5.2f", 0, 36000, 0, 1.0);
273  IUFillNumberVector(&CCDImageExposureNP, CCDImageExposureN, 1, ControlledDeviceT[0].text, "CCD_EXPOSURE", "Expose",
275 
276  IUFillNumber(&CCDImageBinN[0], "HOR_BIN", "X", "%2.0f", 1, 4, 1, 1);
277  IUFillNumber(&CCDImageBinN[1], "VER_BIN", "Y", "%2.0f", 1, 4, 1, 1);
278  IUFillNumberVector(&CCDImageBinNP, CCDImageBinN, 2, ControlledDeviceT[0].text, "CCD_BINNING", "Binning",
280 
281  IUFillSwitch(&CCDUploadS[0], "UPLOAD_CLIENT", "Client", ISS_OFF);
282  IUFillSwitch(&CCDUploadS[1], "UPLOAD_LOCAL", "Local", ISS_ON);
283  IUFillSwitch(&CCDUploadS[2], "UPLOAD_BOTH", "Both", ISS_OFF);
284  IUFillSwitchVector(&CCDUploadSP, CCDUploadS, 3, ControlledDeviceT[0].text, "UPLOAD_MODE", "Upload", OPTIONS_TAB,
285  IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
286 
287  IUFillText(&CCDUploadSettingsT[0], "UPLOAD_DIR", "Dir", "");
288  IUFillText(&CCDUploadSettingsT[1], "UPLOAD_PREFIX", "Prefix", IMAGE_PREFIX);
289  IUFillTextVector(&CCDUploadSettingsTP, CCDUploadSettingsT, 2, ControlledDeviceT[0].text, "UPLOAD_SETTINGS",
290  "Upload Settings", OPTIONS_TAB, IP_RW, 60, IPS_IDLE);
291 
292  IUFillNumber(&FilterSlotN[0], "FILTER_SLOT_VALUE", "Filter", "%3.0f", 1.0, 12.0, 1.0, 1.0);
293  IUFillNumberVector(&FilterSlotNP, FilterSlotN, 1, ControlledDeviceT[1].text, "FILTER_SLOT", "Filter Slot",
295 
296  return true;
297 }
298 
300 {
301  if (isConnected())
302  {
303  defineProperty(&StatusLP);
304  ProgressN[0].value = group = 0;
305  ProgressN[1].value = image = 0;
306  ProgressNP.s = IPS_IDLE;
307  defineProperty(&ProgressNP);
308  BatchSP.s = IPS_IDLE;
309  defineProperty(&BatchSP);
310  DownloadN[0].value = 0;
311  DownloadN[1].value = 0;
312  DownloadNP.s = IPS_IDLE;
313  defineProperty(&DownloadNP);
314  FitsBP.s = IPS_IDLE;
315  defineProperty(&FitsBP);
316  }
317  else
318  {
319  deleteProperty(StatusLP.name);
320  deleteProperty(ProgressNP.name);
321  deleteProperty(BatchSP.name);
322  deleteProperty(DownloadNP.name);
323  deleteProperty(FitsBP.name);
324  }
325  return true;
326 }
327 
328 void Imager::ISGetProperties(const char *dev)
329 {
331 }
332 
333 bool Imager::ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
334 {
335  if (Imager::DEVICE_NAME == dev)
336  {
337  if (std::string{name} == std::string{GroupCountNP.name})
338  {
339  for (int i = 0; i < maxGroup; i++)
340  groups[i]->deleteProperties();
341  IUUpdateNumber(&GroupCountNP, values, names, n);
342  maxGroup = (int)GroupCountN[0].value;
343  if (maxGroup > MAX_GROUP_COUNT)
344  GroupCountN[0].value = maxGroup = MAX_GROUP_COUNT;
345  for (int i = 0; i < maxGroup; i++)
346  groups[i]->defineProperties();
347  GroupCountNP.s = IPS_OK;
348  IDSetNumber(&GroupCountNP, nullptr);
349  return true;
350  }
351  if (std::string{name} == std::string{DownloadNP.name})
352  {
353  IUUpdateNumber(&DownloadNP, values, names, n);
354  initiateDownload();
355  return true;
356  }
357  if (strncmp(name, GROUP_PREFIX, GROUP_PREFIX_LEN) == 0)
358  {
359  for (int i = 0; i < GroupCountN[0].value; i++)
360  if (groups[i]->ISNewNumber(dev, name, values, names, n))
361  {
362  return true;
363  }
364  return false;
365  }
366  }
367  return DefaultDevice::ISNewNumber(dev, name, values, names, n);
368 }
369 
370 bool Imager::ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
371 {
372  if (Imager::DEVICE_NAME == dev)
373  {
374  if (std::string{name} == std::string{BatchSP.name})
375  {
376  for (int i = 0; i < n; i++)
377  {
378  if (strcmp(names[i], BatchS[0].name) == 0 && states[i] == ISS_ON)
379  {
380  if (!isRunning())
381  startBatch();
382  }
383  if (strcmp(names[i], BatchS[1].name) == 0 && states[i] == ISS_ON)
384  {
385  if (isRunning())
386  abortBatch();
387  }
388  }
389  BatchSP.s = IPS_OK;
390  IDSetSwitch(&BatchSP, nullptr);
391  return true;
392  }
393  }
394  return DefaultDevice::ISNewSwitch(dev, name, states, names, n);
395 }
396 
397 bool Imager::ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
398 {
399  if (Imager::DEVICE_NAME == dev)
400  {
401  if (std::string{name} == std::string{ControlledDeviceTP.name})
402  {
403  IUUpdateText(&ControlledDeviceTP, texts, names, n);
404  IDSetText(&ControlledDeviceTP, nullptr);
405  strncpy(StatusL[0].label, ControlledDeviceT[0].text, sizeof(StatusL[0].label));
406  strncpy(CCDImageExposureNP.device, ControlledDeviceT[0].text, sizeof(CCDImageExposureNP.device));
407  strncpy(CCDImageBinNP.device, ControlledDeviceT[0].text, sizeof(CCDImageBinNP.device));
408  strncpy(StatusL[1].label, ControlledDeviceT[1].text, sizeof(StatusL[1].label));
409  strncpy(FilterSlotNP.device, ControlledDeviceT[1].text, sizeof(FilterSlotNP.device));
410  return true;
411  }
412  if (std::string{name} == std::string{ImageNameTP.name})
413  {
414  IUUpdateText(&ImageNameTP, texts, names, n);
415  IDSetText(&ImageNameTP, nullptr);
416  return true;
417  }
418  }
419  return INDI::DefaultDevice::ISNewText(dev, name, texts, names, n);
420 }
421 
422 bool Imager::ISNewBLOB(const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[],
423  char *names[], int n)
424 {
425  return INDI::DefaultDevice::ISNewBLOB(dev, name, sizes, blobsizes, blobs, formats, names, n);
426 }
427 
429 {
431 }
432 
434 {
435  setServer("localhost", 7624); // TODO configuration options
436  watchDevice(controlledCCD);
437  watchDevice(controlledFilterWheel);
438  connectServer();
439  setBLOBMode(B_ALSO, controlledCCD, nullptr);
440 
441  return true;
442 }
443 
445 {
446  if (isRunning())
447  abortBatch();
449  return true;
450 }
451 
452 // BaseClient ----------------------------------------------------------------------------
453 
455 {
456  LOG_DEBUG("Server connected");
457  StatusL[0].s = IPS_ALERT;
458  StatusL[1].s = IPS_ALERT;
459  IDSetLight(&StatusLP, nullptr);
460 }
461 
463 {
464  std::string deviceName{dp->getDeviceName()};
465 
466  LOGF_DEBUG("Device %s detected", deviceName.c_str());
467  if (deviceName == controlledCCD)
468  StatusL[0].s = IPS_BUSY;
469  if (deviceName == controlledFilterWheel)
470  StatusL[1].s = IPS_BUSY;
471 
472  IDSetLight(&StatusLP, nullptr);
473 }
474 
476 {
477  std::string deviceName{property->getDeviceName()};
478 
479  if (strcmp(property->getName(), INDI::SP::CONNECTION) == 0)
480  {
481  bool state = property->getSwitch()->sp[0].s != ISS_OFF;
482  if (deviceName == controlledCCD)
483  {
484  if (state)
485  {
486  StatusL[0].s = IPS_OK;
487  }
488  else
489  {
490  connectDevice(controlledCCD);
491  LOGF_DEBUG("Connecting %s", controlledCCD);
492  }
493  }
494  if (deviceName == controlledFilterWheel)
495  {
496  if (state)
497  {
498  StatusL[1].s = IPS_OK;
499  }
500  else
501  {
502  connectDevice(controlledFilterWheel);
503  LOGF_DEBUG("Connecting %s", controlledFilterWheel);
504  }
505  }
506  IDSetLight(&StatusLP, nullptr);
507  }
508 }
509 
511 {
512  INDI_UNUSED(property);
513 }
514 
516 {
517  INDI_UNUSED(dp);
518 }
519 
521 {
522  if (ProgressNP.s == IPS_BUSY)
523  {
524  char name[128]={0};
525  std::ofstream file;
526 
527  strncpy(format, bp->format, 16);
528  sprintf(name, IMAGE_NAME, ImageNameT[0].text, ImageNameT[1].text, group, image, format);
529  file.open(name, std::ios::out | std::ios::binary | std::ios::trunc);
530  file.write(static_cast<char *>(bp->blob), bp->bloblen);
531  file.close();
532  LOGF_DEBUG("Group %d of %d, image %d of %d, saved to %s", group, maxGroup, image, maxImage,
533  name);
534  if (image == maxImage)
535  {
536  if (group == maxGroup)
537  {
538  batchDone();
539  }
540  else
541  {
542  maxImage = nextGroup()->count();
543  ProgressN[0].value = group = group + 1;
544  ProgressN[1].value = image = 1;
545  IDSetNumber(&ProgressNP, nullptr);
546  initiateNextFilter();
547  }
548  }
549  else
550  {
551  ProgressN[1].value = image = image + 1;
552  IDSetNumber(&ProgressNP, nullptr);
553  initiateNextFilter();
554  }
555  }
556 }
557 
559 {
560  std::string deviceName{svp->device};
561  bool state = svp->sp[0].s != ISS_OFF;
562 
563  if (strcmp(svp->name, INDI::SP::CONNECTION) == 0)
564  {
565  if (deviceName == controlledCCD)
566  {
567  if (state)
568  {
569  StatusL[0].s = IPS_OK;
570  }
571  else
572  {
573  StatusL[0].s = IPS_BUSY;
574  }
575  }
576  if (deviceName == controlledFilterWheel)
577  {
578  if (state)
579  {
580  StatusL[1].s = IPS_OK;
581  }
582  else
583  {
584  StatusL[1].s = IPS_BUSY;
585  }
586  }
587  IDSetLight(&StatusLP, nullptr);
588  }
589 }
590 
592 {
593  std::string deviceName{nvp->device};
594 
595  if (deviceName == controlledCCD)
596  {
597  if (strcmp(nvp->name, "CCD_EXPOSURE") == 0)
598  {
599  ProgressN[2].value = nvp->np[0].value;
600  IDSetNumber(&ProgressNP, nullptr);
601  }
602  }
603  if (deviceName == controlledFilterWheel)
604  {
605  if (strcmp(nvp->name, "FILTER_SLOT") == 0)
606  {
607  FilterSlotN[0].value = nvp->np->value;
608  if (nvp->s == IPS_OK)
609  initiateNextCapture();
610  }
611  }
612 }
613 
615 {
616  std::string deviceName{tvp->device};
617 
618  if (deviceName == controlledCCD)
619  {
620  if (strcmp(tvp->name, "CCD_FILE_PATH") == 0)
621  {
622  char name[128]={0};
623 
624  strncpy(format, strrchr(tvp->tp[0].text, '.'), sizeof(format));
625  sprintf(name, IMAGE_NAME, ImageNameT[0].text, ImageNameT[1].text, group, image, format);
626  rename(tvp->tp[0].text, name);
627  LOGF_DEBUG("Group %d of %d, image %d of %d, saved to %s", group, maxGroup, image,
628  maxImage, name);
629  if (image == maxImage)
630  {
631  if (group == maxGroup)
632  {
633  batchDone();
634  }
635  else
636  {
637  maxImage = nextGroup()->count();
638  ProgressN[0].value = group = group + 1;
639  ProgressN[1].value = image = 1;
640  IDSetNumber(&ProgressNP, nullptr);
641  initiateNextFilter();
642  }
643  }
644  else
645  {
646  ProgressN[1].value = image = image + 1;
647  IDSetNumber(&ProgressNP, nullptr);
648  initiateNextFilter();
649  }
650  }
651  }
652 }
653 
655 {
656  INDI_UNUSED(lvp);
657 }
658 
659 void Imager::newMessage(INDI::BaseDevice *dp, int messageID)
660 {
661  INDI_UNUSED(dp);
662  INDI_UNUSED(messageID);
663 }
664 
665 void Imager::serverDisconnected(int exit_code)
666 {
667  INDI_UNUSED(exit_code);
668  LOG_DEBUG("Server disconnected");
669  StatusL[0].s = IPS_ALERT;
670  StatusL[1].s = IPS_ALERT;
671 }
672 
673 
Imager::getDefaultName
virtual const char * getDefaultName() override
Definition: agent_imager.cpp:213
IP_RO
@ IP_RO
Definition: indiapi.h:183
INDI::BaseClient::connectDevice
void connectDevice(const char *deviceName)
Connect to INDI driver.
Definition: baseclient.cpp:900
indistandardproperty.h
Imager::ISSnoopDevice
virtual bool ISSnoopDevice(XMLEle *root) override
Process a snoop event from INDI server. This function is called when a snooped property is updated in...
Definition: agent_imager.cpp:428
Imager::DEVICE_NAME
static const std::string DEVICE_NAME
Definition: agent_imager.h:30
_IBLOBVectorProperty::s
IPState s
Definition: indiapi.h:484
_ISwitchVectorProperty::device
char device[MAXINDIDEVICE]
Definition: indiapi.h:368
INDI::Property::getName
const char * getName() const
Definition: indiproperty.cpp:289
IPS_OK
@ IPS_OK
Definition: indiapi.h:161
_INumberVectorProperty::s
IPState s
Definition: indiapi.h:332
_ILightVectorProperty
Light vector property descriptor.
Definition: indiapi.h:415
Imager::removeProperty
virtual void removeProperty(INDI::Property *property) override
Emmited when a property is deleted for an INDI driver.
Definition: agent_imager.cpp:510
ISS_OFF
@ ISS_OFF
Definition: indiapi.h:150
Imager::ISNewNumber
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
Definition: agent_imager.cpp:333
INDI::BaseClient::disconnectServer
bool disconnectServer(int exit_code=0)
Disconnect from INDI server.
Definition: baseclient.cpp:882
IDSetText
void IDSetText(const ITextVectorProperty *t, const char *msg,...) ATTRIBUTE_FORMAT_PRINTF(2
Tell client to update an existing text vector property.
IPS_ALERT
@ IPS_ALERT
Definition: indiapi.h:163
Imager::updateProperties
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
Definition: agent_imager.cpp:299
MAX_GROUP_COUNT
#define MAX_GROUP_COUNT
Definition: agent_imager.h:24
IUFillNumber
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: indidriver.c:348
ISR_NOFMANY
@ ISR_NOFMANY
Definition: indiapi.h:174
INDI::DefaultDevice::defineProperty
void defineProperty(INumberVectorProperty *property)
Definition: defaultdevice.cpp:997
OPTIONS_TAB
const char * OPTIONS_TAB
OPTIONS_TAB Where all the driver's options are located. Those may include auxiliary controls,...
Definition: defaultdevice.cpp:39
MAIN_CONTROL_TAB
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
Definition: defaultdevice.cpp:34
group.h
Imager::removeDevice
virtual void removeDevice(INDI::BaseDevice *dp) override
Emmited when a device is deleted from INDI server.
Definition: agent_imager.cpp:515
Imager::newMessage
virtual void newMessage(INDI::BaseDevice *dp, int messageID) override
Emmited when a new message arrives from INDI server.
Definition: agent_imager.cpp:659
IUFillTextVector
void IUFillTextVector(ITextVectorProperty *tvp, IText *tp, int ntp, const char *dev, const char *name, const char *label, const char *group, IPerm p, double timeout, IPState s)
Assign attributes for a text vector property. The vector's auxiliary elements will be set to NULL.
Definition: indidriver.c:477
imager
std::shared_ptr< Imager > imager(new Imager())
INDI_UNUSED
#define INDI_UNUSED(x)
Definition: indidevapi.h:799
GROUP_PREFIX_LEN
#define GROUP_PREFIX_LEN
Definition: agent_imager.cpp:35
MAXINDIBLOBFMT
#define MAXINDIBLOBFMT
Definition: indiapi.h:195
Imager
Definition: agent_imager.h:27
INDI::DefaultDevice::setVersion
void setVersion(uint16_t vMajor, uint16_t vMinor)
Set driver version information to be defined in DRIVER_INFO property as vMajor.vMinor.
Definition: defaultdevice.cpp:1219
INDI::BaseDevice::getDeviceName
const char * getDeviceName() const
Definition: basedevice.cpp:799
Imager::Connect
virtual bool Connect() override
Connect to the device. INDI::DefaultDevice implementation connects to appropriate connection interfac...
Definition: agent_imager.cpp:433
IDSetBLOB
void void void void void void void void void IDSetBLOB(const IBLOBVectorProperty *b, const char *msg,...) ATTRIBUTE_FORMAT_PRINTF(2
Tell client to update an existing BLOB vector property.
IUFillLight
void IUFillLight(ILight *lp, const char *name, const char *label, IPState s)
Assign attributes for a light property. The light's auxiliary elements will be set to NULL.
Definition: indidriver.c:334
Imager::newBLOB
virtual void newBLOB(IBLOB *bp) override
Emmited when a new BLOB value arrives from INDI server.
Definition: agent_imager.cpp:520
Imager::newDevice
virtual void newDevice(INDI::BaseDevice *dp) override
Emmited when a new device is created from INDI server.
Definition: agent_imager.cpp:462
IUFillText
void IUFillText(IText *tp, const char *name, const char *label, const char *initialText)
Assign attributes for a text property. The text's auxiliary elements will be set to NULL.
Definition: indidriver.c:369
Imager::ISNewText
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) override
Process the client newSwitch command.
Definition: agent_imager.cpp:397
_ITextVectorProperty::device
char device[MAXINDIDEVICE]
Definition: indiapi.h:247
IUUpdateText
int IUUpdateText(ITextVectorProperty *tvp, char *texts[], char *names[], int n)
Update all text members in a text vector property.
Definition: indidriver.c:259
Imager::newLight
virtual void newLight(ILightVectorProperty *lvp) override
Emmited when a new light value arrives from INDI server.
Definition: agent_imager.cpp:654
agent_imager.h
INDI::DefaultDevice::initProperties
virtual bool initProperties()
Initilize properties initial state and value. The child class must implement this function.
Definition: defaultdevice.cpp:917
_ILightVectorProperty::name
char name[MAXINDINAME]
Definition: indiapi.h:420
INDI::Property
Provides generic container for INDI properties.
Definition: indiproperty.h:43
INDI::BaseClient::watchDevice
void watchDevice(const char *deviceName)
Add a device to the watch list.
Definition: baseclient.cpp:863
Imager::serverConnected
virtual void serverConnected() override
Emmited when the server is connected.
Definition: agent_imager.cpp:454
_ITextVectorProperty
Text vector property descriptor.
Definition: indiapi.h:244
ISNewNumber
void ISNewNumber(const char *dev, const char *name, double *values, char *names[], int n)
Update the value of an existing number vector property.
INDI::BaseClient::sendNewNumber
void sendNewNumber(INumberVectorProperty *pp)
Send new Number command to server.
Definition: baseclient.cpp:976
Imager::newText
virtual void newText(ITextVectorProperty *tvp) override
Emmited when a new text value arrives from INDI server.
Definition: agent_imager.cpp:614
LOGF_DEBUG
#define LOGF_DEBUG(fmt,...)
Definition: indilogger.h:83
INDI::DefaultDevice::ISSnoopDevice
virtual bool ISSnoopDevice(XMLEle *root)
Process a snoop event from INDI server. This function is called when a snooped property is updated in...
Definition: defaultdevice.cpp:633
Imager::Disconnect
virtual bool Disconnect() override
Disconnect from device.
Definition: agent_imager.cpp:444
_ITextVectorProperty::tp
IText * tp
Definition: indiapi.h:261
ISGetProperties
void ISGetProperties(const char *dev)
Get Device Properties.
Definition: defaultdevice.cpp:53
_INumberVectorProperty
Number vector property descriptor.
Definition: indiapi.h:317
IDSetLight
void void void void void void void IDSetLight(const ILightVectorProperty *l, const char *msg,...) ATTRIBUTE_FORMAT_PRINTF(2
Tell client to update an existing light vector property.
B_ALSO
@ B_ALSO
Definition: indidevapi.h:271
IUFillSwitchVector
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: indidriver.c:412
IUFillNumberVector
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: indidriver.c:455
IPS_BUSY
@ IPS_BUSY
Definition: indiapi.h:162
ISR_1OFMANY
@ ISR_1OFMANY
Definition: indiapi.h:172
_INumberVectorProperty::np
INumber * np
Definition: indiapi.h:334
IPS_IDLE
@ IPS_IDLE
Definition: indiapi.h:160
GROUP_PREFIX
#define GROUP_PREFIX
Definition: agent_imager.cpp:34
xml_ele_
Definition: lilxml.c:105
_INumberVectorProperty::name
char name[MAXINDINAME]
Definition: indiapi.h:322
_ITextVectorProperty::name
char name[MAXINDINAME]
Definition: indiapi.h:249
INDI::BaseDevice::isConnected
bool isConnected() const
Definition: basedevice.cpp:518
INDI::BaseClient::setBLOBMode
void setBLOBMode(BLOBHandling blobH, const char *dev, const char *prop=nullptr)
Set Binary Large Object policy mode.
Definition: baseclient.cpp:1066
ISNewSwitch
void ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Update the value of an existing switch vector property.
Definition: defaultdevice.cpp:60
IUFillBLOB
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: indidriver.c:390
IMAGE_PREFIX
#define IMAGE_PREFIX
Definition: agent_imager.cpp:31
LOG_DEBUG
#define LOG_DEBUG(txt)
Definition: indilogger.h:75
Imager::newSwitch
virtual void newSwitch(ISwitchVectorProperty *svp) override
Emmited when a new switch value arrives from INDI server.
Definition: agent_imager.cpp:558
Imager::ISNewBLOB
virtual bool ISNewBLOB(const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n) override
Process the client newBLOB command.
Definition: agent_imager.cpp:422
INDI::BaseClient::sendNewSwitch
void sendNewSwitch(ISwitchVectorProperty *pp)
Send new Switch command to server.
Definition: baseclient.cpp:1006
IMAGE_NAME
#define IMAGE_NAME
Definition: agent_imager.cpp:30
IUSaveText
void IUSaveText(IText *tp, const char *newtext)
Function to reliably save new text in a IText.
Definition: indicom.c:1428
INDI::BaseClient::sendNewText
void sendNewText(ITextVectorProperty *pp)
Send new Text command to server.
Definition: baseclient.cpp:946
_ISwitchVectorProperty::s
IPState s
Definition: indiapi.h:382
Imager::serverDisconnected
virtual void serverDisconnected(int exit_code) override
Emmited when the server gets disconnected.
Definition: agent_imager.cpp:665
_INumberVectorProperty::device
char device[MAXINDIDEVICE]
Definition: indiapi.h:320
Imager::ISGetProperties
virtual void ISGetProperties(const char *dev) override
define the driver's properties to the client. Usually, only a minimum set of properties are defined t...
Definition: agent_imager.cpp:328
INDI::DefaultDevice::ISNewBLOB
virtual bool ISNewBLOB(const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n)
Process the client newBLOB command.
Definition: defaultdevice.cpp:623
IUUpdateNumber
int IUUpdateNumber(INumberVectorProperty *nvp, double values[], char *names[], int n)
Update all numbers in a number vector property.
Definition: indidriver.c:225
_IBLOBVectorProperty::name
char name[MAXINDINAME]
Definition: indiapi.h:474
IP_RW
@ IP_RW
Definition: indiapi.h:185
Imager::Imager
Imager()
Definition: agent_imager.cpp:43
DOWNLOAD_TAB
#define DOWNLOAD_TAB
Definition: agent_imager.cpp:29
ISState
ISState
Switch state.
Definition: indiapi.h:148
_ISwitchVectorProperty::sp
ISwitch * sp
Definition: indiapi.h:384
INDI::SP::CONNECTION
const char * CONNECTION
Connect to and disconnect from device.
Definition: indistandardproperty.cpp:63
INDI::BaseClient::setServer
void setServer(const char *hostname, unsigned int port)
Set the server host name and port.
Definition: baseclient.cpp:856
INDI::DefaultDevice::addDebugControl
void addDebugControl()
Add Debug control to the driver.
Definition: defaultdevice.cpp:639
IUFillBLOBVector
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: indidriver.c:499
INDI::DefaultDevice::deleteProperty
virtual bool deleteProperty(const char *propertyName)
Delete a property and unregister it. It will also be deleted from all clients.
Definition: defaultdevice.cpp:965
IUFillLightVector
void IUFillLightVector(ILightVectorProperty *lvp, ILight *lp, int nlp, const char *dev, const char *name, const char *label, const char *group, IPState s)
Assign attributes for a light vector property. The vector's auxiliary elements will be set to NULL.
Definition: indidriver.c:435
Imager::ISNewSwitch
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
Definition: agent_imager.cpp:370
Imager::initProperties
virtual bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
Definition: agent_imager.cpp:218
Imager::newNumber
virtual void newNumber(INumberVectorProperty *nvp) override
Emmited when a new number value arrives from INDI server.
Definition: agent_imager.cpp:591
INDI::DefaultDevice::ISNewText
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
Process the client newSwitch command.
Definition: defaultdevice.cpp:614
IDSetNumber
void void void IDSetNumber(const INumberVectorProperty *n, const char *msg,...) ATTRIBUTE_FORMAT_PRINTF(2
Tell client to update an existing number vector property.
IDSetSwitch
void void void void void IDSetSwitch(const ISwitchVectorProperty *s, const char *msg,...) ATTRIBUTE_FORMAT_PRINTF(2
Tell client to update an existing switch vector property.
INDI::BaseDevice
Class to provide basic INDI device functionality.
Definition: basedevice.h:45
Imager::newProperty
virtual void newProperty(INDI::Property *property) override
Emmited when a new property is created for an INDI driver.
Definition: agent_imager.cpp:475
IBLOB
One Blob (Binary Large Object) descriptor.
IUFillSwitch
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: indidriver.c:320
_ISwitchVectorProperty
Switch vector property descriptor.
Definition: indiapi.h:365
INDI::BaseClient::connectServer
bool connectServer()
Connect to INDI server.
Definition: baseclient.cpp:876
_ISwitchVectorProperty::name
char name[MAXINDINAME]
Definition: indiapi.h:370
ISS_ON
@ ISS_ON
Definition: indiapi.h:151