Instrument Neutral Distributed Interface INDI  0.9.9
indifocuser.cpp
1 /*******************************************************************************
2  Copyright(c) 2013 Jasem Mutlaq. All rights reserved.
3 
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Library General Public
6  License version 2 as published by the Free Software Foundation.
7 
8  This library is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  Library General Public License for more details.
12 
13  You should have received a copy of the GNU Library General Public License
14  along with this library; see the file COPYING.LIB. If not, write to
15  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16  Boston, MA 02110-1301, USA.
17 *******************************************************************************/
18 
19 #include "indifocuser.h"
20 
21 #include <string.h>
22 
23 INDI::Focuser::Focuser()
24 {
25  controller = new INDI::Controller(this);
26 
27  controller->setButtonCallback(buttonHelper);
28 }
29 
30 INDI::Focuser::~Focuser()
31 {
32 }
33 
35 {
36  DefaultDevice::initProperties(); // let the base class flesh in what it wants
37 
38  initFocuserProperties(getDeviceName(), MAIN_CONTROL_TAB);
39 
40  /* Port */
41  IUFillText(&PortT[0], "PORT", "Port", "/dev/ttyUSB0");
42  IUFillTextVector(&PortTP, PortT, 1, getDeviceName(), "DEVICE_PORT", "Ports", MAIN_CONTROL_TAB, IP_RW, 0, IPS_IDLE);
43 
44  // Presets
45  IUFillNumber(&PresetN[0], "Preset 1", "", "%6.2f", 0, 60000, 1000, 0);
46  IUFillNumber(&PresetN[1], "Preset 2", "", "%6.2f", 0, 60000, 1000, 0);
47  IUFillNumber(&PresetN[2], "Preset 3", "", "%6.2f", 0, 60000, 1000, 0);
48  IUFillNumberVector(&PresetNP, PresetN, 3, getDeviceName(), "Presets", "", "Presets", IP_RW, 0, IPS_IDLE);
49 
50  //Preset GOTO
51  IUFillSwitch(&PresetGotoS[0], "Preset 1", "", ISS_OFF);
52  IUFillSwitch(&PresetGotoS[1], "Preset 2", "", ISS_OFF);
53  IUFillSwitch(&PresetGotoS[2], "Preset 3", "", ISS_OFF);
54  IUFillSwitchVector(&PresetGotoSP, PresetGotoS, 3, getDeviceName(), "Goto", "", "Presets", IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
55 
56  addDebugControl();
57 
58  controller->mapController("Focus In", "Focus In", INDI::Controller::CONTROLLER_BUTTON, "BUTTON_1");
59  controller->mapController("Focus Out", "Focus Out", INDI::Controller::CONTROLLER_BUTTON, "BUTTON_2");
60 
61  controller->initProperties();
62 
63  return true;
64 }
65 
66 void INDI::Focuser::ISGetProperties (const char *dev)
67 {
68  // First we let our parent populate
70 
71  defineText(&PortTP);
72 
73  controller->ISGetProperties(dev);
74  return;
75 }
76 
78 {
79  if(isConnected())
80  {
81  // Now we add our focusser specific stuff
82  defineSwitch(&FocusMotionSP);
83 
84  if (variableSpeed)
85  {
86  defineNumber(&FocusSpeedNP);
87  defineNumber(&FocusTimerNP);
88  }
89  if (canRelMove)
90  defineNumber(&FocusRelPosNP);
91  if (canAbsMove)
92  defineNumber(&FocusAbsPosNP);
93  if (canAbort)
94  defineSwitch(&AbortSP);
95  if (canAbsMove)
96  {
97  defineNumber(&PresetNP);
98  defineSwitch(&PresetGotoSP);
99  }
100  } else
101  {
102  deleteProperty(FocusMotionSP.name);
103  if (variableSpeed)
104  {
105  deleteProperty(FocusSpeedNP.name);
106  deleteProperty(FocusTimerNP.name);
107  }
108  if (canRelMove)
109  deleteProperty(FocusRelPosNP.name);
110  if (canAbsMove)
111  deleteProperty(FocusAbsPosNP.name);
112  if (canAbort)
113  deleteProperty(AbortSP.name);
114  if (canAbsMove)
115  {
116  deleteProperty(PresetNP.name);
117  deleteProperty(PresetGotoSP.name);
118  }
119  }
120 
121  controller->updateProperties();
122  return true;
123 }
124 
125 
126 bool INDI::Focuser::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
127 {
128  // first check if it's for our device
129  if(strcmp(dev,getDeviceName())==0)
130  {
131  if (!strcmp(name, PresetNP.name))
132  {
133  IUUpdateNumber(&PresetNP, values, names, n);
134  PresetNP.s = IPS_OK;
135  IDSetNumber(&PresetNP, NULL);
136 
137  saveConfig();
138 
139  return true;
140  }
141 
142  if (strstr(name, "FOCUS_"))
143  return processFocuserNumber(dev, name, values, names, n);
144 
145  }
146 
147  return DefaultDevice::ISNewNumber(dev,name,values,names,n);
148 }
149 
150 bool INDI::Focuser::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
151 {
152  if(strcmp(dev,getDeviceName())==0)
153  {
154  if (!strcmp(PresetGotoSP.name, name))
155  {
156  IUUpdateSwitch(&PresetGotoSP, states, names, n);
157  int index = IUFindOnSwitchIndex(&PresetGotoSP);
158  int rc = MoveAbs(PresetN[index].value);
159  if (rc >= 0)
160  {
161  PresetGotoSP.s = IPS_OK;
162  DEBUGF(INDI::Logger::DBG_SESSION, "Moving to Preset %d with position %g.", index+1, PresetN[index].value);
163  IDSetSwitch(&PresetGotoSP, NULL);
164  return true;
165  }
166 
167  PresetGotoSP.s = IPS_ALERT;
168  IDSetSwitch(&PresetGotoSP, NULL);
169  return false;
170  }
171 
172  if (strstr(name, "FOCUS_"))
173  return processFocuserSwitch(dev, name, states, names, n);
174 
175  }
176 
177  controller->ISNewSwitch(dev, name, states, names, n);
178 
179  // Nobody has claimed this, so, ignore it
180  return DefaultDevice::ISNewSwitch(dev,name,states,names,n);
181 }
182 
183 bool INDI::Focuser::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
184 {
185  if(strcmp(dev,getDeviceName())==0)
186  {
187  if (!strcmp(name, PortTP.name))
188  {
189  IUUpdateText(&PortTP, texts, names, n);
190  PortTP.s = IPS_OK;
191  IDSetText(&PortTP, NULL);
192  return true;
193  }
194  }
195 
196  controller->ISNewText(dev, name, texts, names, n);
197 
198  return DefaultDevice::ISNewText(dev, name, texts, names, n);
199 }
200 
201 bool INDI::Focuser::ISSnoopDevice (XMLEle *root)
202 {
203  controller->ISSnoopDevice(root);
204 
206 }
207 
209 {
210  IUSaveConfigText(fp, &PortTP);
211  IUSaveConfigNumber(fp, &PresetNP);
212 
213  controller->saveConfigItems(fp);
214 
215  return true;
216 }
217 
218 void INDI::Focuser::buttonHelper(const char *button_n, ISState state, void *context)
219 {
220  static_cast<INDI::Focuser *>(context)->processButton(button_n, state);
221 }
222 
223 void INDI::Focuser::processButton(const char * button_n, ISState state)
224 {
225  //ignore OFF
226  if (state == ISS_OFF)
227  return;
228 
229  int rc=0;
230  // Focus In
231  if (!strcmp(button_n, "Focus In"))
232  {
233  if (variableSpeed)
234  {
235  rc = Move(FOCUS_INWARD, FocusSpeedN[0].value, FocusTimerN[0].value);
236  if (rc == 0)
237  FocusTimerNP.s = IPS_OK;
238  else if (rc == 1)
239  FocusTimerNP.s = IPS_BUSY;
240  else
241  FocusTimerNP.s = IPS_ALERT;
242 
243  IDSetNumber(&FocusTimerNP,NULL);
244  }
245  else if (canRelMove)
246  {
247  rc=MoveRel(FOCUS_INWARD, FocusRelPosN[0].value);
248  if (rc == 0)
249  {
250  FocusRelPosNP.s=IPS_OK;
251  IDSetNumber(&FocusRelPosNP, "Focuser moved %d steps inward", (int) FocusRelPosN[0].value);
252  IDSetNumber(&FocusAbsPosNP, NULL);
253  }
254  else if (rc == 1)
255  {
256  FocusRelPosNP.s=IPS_BUSY;
257  IDSetNumber(&FocusAbsPosNP, "Focuser is moving %d steps inward...", (int) FocusRelPosN[0].value);
258  }
259  }
260  }
261  else if (!strcmp(button_n, "Focus Out"))
262  {
263  if (variableSpeed)
264  {
265  rc = Move(FOCUS_OUTWARD, FocusSpeedN[0].value, FocusTimerN[0].value);
266  if (rc == 0)
267  FocusTimerNP.s = IPS_OK;
268  else if (rc == 1)
269  FocusTimerNP.s = IPS_BUSY;
270  else
271  FocusTimerNP.s = IPS_ALERT;
272 
273  IDSetNumber(&FocusTimerNP,NULL);
274  }
275  else if (canRelMove)
276  {
277  rc=MoveRel(FOCUS_OUTWARD, FocusRelPosN[0].value);
278  if (rc == 0)
279  {
280  FocusRelPosNP.s=IPS_OK;
281  IDSetNumber(&FocusRelPosNP, "Focuser moved %d steps outward", (int) FocusRelPosN[0].value);
282  IDSetNumber(&FocusAbsPosNP, NULL);
283  }
284  else if (rc == 1)
285  {
286  FocusRelPosNP.s=IPS_BUSY;
287  IDSetNumber(&FocusAbsPosNP, "Focuser is moving %d steps outward...", (int) FocusRelPosN[0].value);
288  }
289  }
290  }
291 }
void IUSaveConfigText(FILE *fp, const ITextVectorProperty *tvp)
Add a text vector property value to the configuration file.
Definition: indidriver.c:1330
void setButtonCallback(buttonFunc buttonCallback)
setButtonCallback Sets the callback function when a new button input is detected. ...
virtual bool updateProperties()
updateProperties is called whenever there is a change in the CONNECTION status of the driver...
Definition: indifocuser.cpp:77
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Process the client newSwitch command.
virtual bool saveConfigItems(FILE *fp)
saveConfigItems Saves the Device Port and Focuser Presets in the configuration file ...
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:502
virtual void ISGetProperties(const char *dev)
define the driver's properties to the client. Usually, only a minumum set of properties are defined t...
void IDSetText(const ITextVectorProperty *t, const char *msg,...)
Tell client to update an existing text vector property.
Definition: indidriver.c:1683
void IDSetSwitch(const ISwitchVectorProperty *s, const char *msg,...)
Tell client to update an existing switch vector property.
Definition: indidriver.c:1763
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
Process the client newNumber command.
int IUUpdateSwitch(ISwitchVectorProperty *svp, ISState *states, char *names[], int n)
Update all switches in a switch vector property.
Definition: indidriver.c:209
int IUUpdateText(ITextVectorProperty *tvp, char *texts[], char *names[], int n)
Update all text members in a text vector property.
Definition: indidriver.c:300
The Controller class provides functionality to access a controller (e.g. joystick) input and send it ...
int IUUpdateNumber(INumberVectorProperty *nvp, double values[], char *names[], int n)
Update all numbers in a number vector property.
Definition: indidriver.c:263
Definition: indiapi.h:139
void IDSetNumber(const INumberVectorProperty *n, const char *msg,...)
Tell client to update an existing number vector property.
Definition: indidriver.c:1723
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:419
void IUSaveConfigNumber(FILE *fp, const INumberVectorProperty *nvp)
Add a number vector property value to the configuration file.
Definition: indidriver.c:1311
virtual void ISGetProperties(const char *dev)
define the driver's properties to the client. Usually, only a minumum set of properties are defined t...
Definition: indifocuser.cpp:66
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:367
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:398
int IUFindOnSwitchIndex(const ISwitchVectorProperty *sp)
Returns the index of first ON switch it finds in the vector switch property.
Definition: indicom.c:1159
Class to provide general functionality of a focuser device.
Definition: indifocuser.h:37
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
Process the client newNumber command.
virtual bool ISSnoopDevice(XMLEle *root)
Process a snoop event from INDI server. This function is called when a snooped property is updated in...
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
Process the client newSwitch command.
virtual bool ISSnoopDevice(XMLEle *root)
Process a snoop event from INDI server. This function is called when a snooped property is updated in...
virtual bool initProperties()
Initilize properties initial state and value. The child class must implement this function...
ISState
Switch state.
Definition: indiapi.h:105
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:460
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:525
virtual bool initProperties()
Initilize properties initial state and value. The child class must implement this function...
Definition: indifocuser.cpp:34
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Process the client newSwitch command.
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
Process the client newSwitch command.