1 /* 2 SPDX-FileCopyrightText: 2012 Jasem Mutlaq <mutlaqja@ikarustech.com> 3 4 SPDX-License-Identifier: GPL-2.0-or-later 5 */ 6 7 #include <basedevice.h> 8 #include "indifocuser.h" 9 #include "clientmanager.h" 10 11 namespace ISD 12 { 13 registerProperty(INDI::Property prop)14void Focuser::registerProperty(INDI::Property prop) 15 { 16 if (!prop.getRegistered()) 17 return; 18 19 if (prop.isNameMatch("FOCUS_MAX")) 20 { 21 auto nvp = prop.getNumber(); 22 m_maxPosition = nvp->at(0)->getValue(); 23 } 24 25 DeviceDecorator::registerProperty(prop); 26 } 27 processLight(ILightVectorProperty * lvp)28void Focuser::processLight(ILightVectorProperty *lvp) 29 { 30 DeviceDecorator::processLight(lvp); 31 } 32 processNumber(INumberVectorProperty * nvp)33void Focuser::processNumber(INumberVectorProperty *nvp) 34 { 35 if (!strcmp(nvp->name, "FOCUS_MAX")) 36 { 37 m_maxPosition = nvp->np[0].value; 38 } 39 40 DeviceDecorator::processNumber(nvp); 41 } 42 processSwitch(ISwitchVectorProperty * svp)43void Focuser::processSwitch(ISwitchVectorProperty *svp) 44 { 45 DeviceDecorator::processSwitch(svp); 46 } 47 processText(ITextVectorProperty * tvp)48void Focuser::processText(ITextVectorProperty *tvp) 49 { 50 DeviceDecorator::processText(tvp); 51 } 52 focusIn()53bool Focuser::focusIn() 54 { 55 auto focusProp = baseDevice->getSwitch("FOCUS_MOTION"); 56 57 if (!focusProp) 58 return false; 59 60 auto inFocus = focusProp->findWidgetByName("FOCUS_INWARD"); 61 62 if (!inFocus) 63 return false; 64 65 if (inFocus->getState() == ISS_ON) 66 return true; 67 68 focusProp->reset(); 69 inFocus->setState(ISS_ON); 70 71 clientManager->sendNewSwitch(focusProp); 72 73 return true; 74 } 75 stop()76bool Focuser::stop() 77 { 78 auto focusStop = baseDevice->getSwitch("FOCUS_ABORT_MOTION"); 79 80 if (!focusStop) 81 return false; 82 83 focusStop->at(0)->setState(ISS_ON); 84 clientManager->sendNewSwitch(focusStop); 85 86 return true; 87 } 88 focusOut()89bool Focuser::focusOut() 90 { 91 auto focusProp = baseDevice->getSwitch("FOCUS_MOTION"); 92 93 if (!focusProp) 94 return false; 95 96 auto outFocus = focusProp->findWidgetByName("FOCUS_OUTWARD"); 97 98 if (!outFocus) 99 return false; 100 101 if (outFocus->getState() == ISS_ON) 102 return true; 103 104 focusProp->reset(); 105 outFocus->setState(ISS_ON); 106 107 clientManager->sendNewSwitch(focusProp); 108 109 return true; 110 } 111 getFocusDirection(ISD::Focuser::FocusDirection * dir)112bool Focuser::getFocusDirection(ISD::Focuser::FocusDirection *dir) 113 { 114 auto focusProp = baseDevice->getSwitch("FOCUS_MOTION"); 115 116 if (!focusProp) 117 return false; 118 119 auto inFocus = focusProp->findWidgetByName("FOCUS_INWARD"); 120 121 if (!inFocus) 122 return false; 123 124 if (inFocus->getState() == ISS_ON) 125 *dir = FOCUS_INWARD; 126 else 127 *dir = FOCUS_OUTWARD; 128 129 return true; 130 } 131 moveByTimer(int msecs)132bool Focuser::moveByTimer(int msecs) 133 { 134 auto focusProp = baseDevice->getNumber("FOCUS_TIMER"); 135 136 if (!focusProp) 137 return false; 138 139 focusProp->at(0)->setValue(msecs); 140 141 clientManager->sendNewNumber(focusProp); 142 143 return true; 144 } 145 moveAbs(int steps)146bool Focuser::moveAbs(int steps) 147 { 148 auto focusProp = baseDevice->getNumber("ABS_FOCUS_POSITION"); 149 150 if (!focusProp) 151 return false; 152 153 focusProp->at(0)->setValue(steps); 154 155 clientManager->sendNewNumber(focusProp); 156 157 return true; 158 } 159 canAbsMove()160bool Focuser::canAbsMove() 161 { 162 auto focusProp = baseDevice->getNumber("ABS_FOCUS_POSITION"); 163 164 if (!focusProp) 165 return false; 166 else 167 return true; 168 } 169 moveRel(int steps)170bool Focuser::moveRel(int steps) 171 { 172 INDI::PropertyView<INumber> *focusProp; 173 174 if(canManualFocusDriveMove()) 175 { 176 focusProp = baseDevice->getNumber("manualfocusdrive"); 177 178 FocusDirection dir; 179 getFocusDirection(&dir); 180 if (dir == FOCUS_INWARD) 181 steps = -abs(steps); 182 else if (dir == FOCUS_OUTWARD) 183 steps = abs(steps); 184 185 //manualfocusdrive needs different steps value at every turn 186 if (steps == getLastManualFocusDriveValue()) 187 steps += 1; 188 189 //Nikon Z6 fails if step is -1, 0, 1 190 if (deviation == NIKONZ6) 191 { 192 if (abs(steps) < 2) 193 steps = 2; 194 } 195 } 196 else 197 { 198 focusProp = baseDevice->getNumber("REL_FOCUS_POSITION"); 199 } 200 201 if (!focusProp) 202 return false; 203 204 focusProp->at(0)->setValue(steps); 205 206 clientManager->sendNewNumber(focusProp); 207 208 return true; 209 } 210 canRelMove()211bool Focuser::canRelMove() 212 { 213 auto focusProp = baseDevice->getNumber("REL_FOCUS_POSITION"); 214 215 if (!focusProp) 216 return false; 217 else 218 return true; 219 } 220 canManualFocusDriveMove()221bool Focuser::canManualFocusDriveMove() 222 { 223 auto focusProp = baseDevice->getNumber("manualfocusdrive"); 224 225 if (!focusProp) 226 return false; 227 else 228 return true; 229 } 230 getLastManualFocusDriveValue()231double Focuser::getLastManualFocusDriveValue() 232 { 233 auto focusProp = baseDevice->getNumber("manualfocusdrive"); 234 235 if (!focusProp) 236 return 0; 237 238 return (double)focusProp->at(0)->getValue(); 239 } 240 241 canTimerMove()242bool Focuser::canTimerMove() 243 { 244 auto focusProp = baseDevice->getNumber("FOCUS_TIMER"); 245 246 if (!focusProp) 247 return false; 248 else 249 return true; 250 } 251 setmaxPosition(uint32_t steps)252bool Focuser::setmaxPosition(uint32_t steps) 253 { 254 auto focusProp = baseDevice->getNumber("FOCUS_MAX"); 255 256 if (!focusProp) 257 return false; 258 259 focusProp->at(0)->setValue(steps); 260 clientManager->sendNewNumber(focusProp); 261 262 return true; 263 } 264 hasBacklash()265bool Focuser::hasBacklash() 266 { 267 auto focusProp = baseDevice->getNumber("FOCUS_BACKLASH_STEPS"); 268 return (focusProp != nullptr); 269 } 270 setBacklash(int32_t steps)271bool Focuser::setBacklash(int32_t steps) 272 { 273 auto focusToggle = baseDevice->getSwitch("FOCUS_BACKLASH_TOGGLE"); 274 if (!focusToggle) 275 return false; 276 277 // Make sure focus compensation is enabled. 278 if (steps != 0 && focusToggle->at(0)->getState() != ISS_ON) 279 { 280 focusToggle->reset(); 281 focusToggle->at(0)->setState(ISS_ON); 282 focusToggle->at(1)->setState(ISS_OFF); 283 clientManager->sendNewSwitch(focusToggle); 284 } 285 286 auto focusProp = baseDevice->getNumber("FOCUS_BACKLASH_STEPS"); 287 if (!focusProp) 288 return false; 289 290 focusProp->at(0)->setValue(steps); 291 clientManager->sendNewNumber(focusProp); 292 293 // If steps = 0, disable compensation 294 if (steps == 0 && focusToggle->at(0)->getState() == ISS_ON) 295 { 296 focusToggle->reset(); 297 focusToggle->at(0)->setState(ISS_OFF); 298 focusToggle->at(1)->setState(ISS_ON); 299 clientManager->sendNewSwitch(focusToggle); 300 } 301 return true; 302 } 303 getBacklash()304int32_t Focuser::getBacklash() 305 { 306 auto focusProp = baseDevice->getNumber("FOCUS_BACKLASH_STEPS"); 307 if (!focusProp) 308 return -1; 309 310 return focusProp->at(0)->getValue(); 311 } 312 hasDeviation()313bool Focuser::hasDeviation() 314 { 315 if (getDeviceName() == "Nikon DSLR Z6") 316 { 317 deviation = NIKONZ6; 318 return true; 319 } 320 return false; 321 } 322 323 } 324