92static std::unique_ptr<DreamFocuser> dreamFocuser(
new DreamFocuser());
142 TemperatureNP[0].
fill(
"TEMPERATURE",
"Celsius",
"%6.2f", -100, 100, 0, 0);
147 WeatherNP[FOCUS_HUMIDITY].
fill(
"FOCUS_HUMIDITY",
"Humidity [%]",
"%6.1f", 0, 100, 0, 0);
148 WeatherNP[FOCUS_DEWPOINT].
fill(
"FOCUS_DEWPOINT",
"Dew point [C]",
"%6.1f", -100, 100, 0, 0);
153 StatusSP[ABSOLUTE].
fill(
"ABSOLUTE",
"Absolute",
ISS_OFF);
154 StatusSP[MOVING].
fill(
"MOVING",
"Moving",
ISS_OFF);
155 StatusSP[PARKED].
fill(
"PARKED",
"Parked",
ISS_OFF);
294 ParkSP.
update(states, names, n);
320 return setSync(ticks);
328bool DreamFocuser::getTemperature()
330 if ( dispatch_command(
'T') )
332 currentTemperature = ((
short int)( (currentResponse.
c << 8) | currentResponse.
d )) / 10.;
333 currentHumidity = ((
short int)( (currentResponse.
a << 8) | currentResponse.
b )) / 10.;
345bool DreamFocuser::getStatus()
348 if ( dispatch_command(
'I') )
350 isMoving = ( currentResponse.
d & 3 ) != 0 ?
true : false;
352 isParked = (currentResponse.
d >> 3) & 3;
353 isVcc12V = ( (currentResponse.
d >> 5) & 1 ) == 1;
358 if ( dispatch_command(
'W') )
359 isAbsolute = currentResponse.
d == 1 ?
true : false;
367bool DreamFocuser::getPosition()
371 if ( dispatch_command(
'P') )
372 currentPosition = (currentResponse.
a << 24) | (currentResponse.
b << 16) | (currentResponse.
c << 8) | currentResponse.
d;
380bool DreamFocuser::setPosition( int32_t position)
382 if ( dispatch_command(
'M', position) )
383 if ( ((currentResponse.
a << 24) | (currentResponse.
b << 16) | (currentResponse.
c << 8) | currentResponse.
d) == position )
385 LOGF_DEBUG(
"Moving to position %d", position);
391bool DreamFocuser::getMaxPosition()
393 if ( dispatch_command(
'A', 0, 3) )
395 currentMaxPosition = (currentResponse.
a << 24) | (currentResponse.
b << 16) | (currentResponse.
c << 8) | currentResponse.
d;
396 LOGF_DEBUG(
"getMaxPosition: %d", currentMaxPosition);
406bool DreamFocuser::setSync( uint32_t position)
408 if ( dispatch_command(
'Z', position) )
409 if (
static_cast<uint32_t
>((currentResponse.
a << 24) | (currentResponse.
b << 16) | (currentResponse.
c << 8) |
410 currentResponse.
d) == position )
412 LOGF_DEBUG(
"Syncing to position %d", position);
419bool DreamFocuser::setPark()
421 if (isAbsolute ==
false)
423 LOG_ERROR(
"Focuser is not in Absolute mode. Please sync before to allow parking.");
427 if ( dispatch_command(
'G') )
438 if ( dispatch_command(
'H') )
477 if (isAbsolute ==
false)
479 LOG_ERROR(
"Focuser is not in Absolute mode. Please sync.");
485 LOG_ERROR(
"Please unpark before issuing any motion commands.");
488 if ( setPosition(ticks) )
499 int32_t finalTicks = currentPosition + ((int32_t)ticks * (dir ==
FOCUS_INWARD ? -1 : 1));
501 LOGF_DEBUG(
"MoveRelPosition: %d", finalTicks);
505 LOG_ERROR(
"Please unpark before issuing any motion commands.");
509 if ( setPosition(finalTicks) )
526 int32_t oldPosition = currentPosition;
528 if ( getMaxPosition() )
561 StatusSP[PARKED].s =
ISS_ON;
564 else if ( isParked == 2 )
600 if ( getTemperature() )
604 TemperatureNP[0].setValue(currentTemperature);
605 WeatherNP[FOCUS_HUMIDITY].setValue(currentHumidity);
606 WeatherNP[FOCUS_DEWPOINT].setValue(pow(currentHumidity / 100, 1.0 / 8) * (112 + 0.9 * currentTemperature) + 0.1 * currentTemperature - 112);
618 if ( oldPosition != currentPosition )
640 TemperatureNP.
apply();
656unsigned char DreamFocuser::calculate_checksum(DreamFocuserCommand c)
661 z = (c.M + c.k + c.a + c.b + c.c + c.d + c.addr) & 0xff;
665bool DreamFocuser::send_command(
char k, uint32_t l,
unsigned char addr)
667 DreamFocuserCommand c;
668 int err_code = 0, nbytes_written = 0;
670 unsigned char *x = (
unsigned char *)&l;
719 c.z = calculate_checksum(c);
721 LOGF_DEBUG(
"Sending command: c=%c, a=%hhu, b=%hhu, c=%hhu, d=%hhu ($%hhx), n=%hhu, z=%hhu", c.k, c.a, c.b, c.c, c.d, c.d,
724 tcflush(
PortFD, TCIOFLUSH);
729 LOGF_ERROR(
"TTY error detected: %s", dreamFocuser_error);
733 LOGF_DEBUG(
"Sending complete. Number of bytes written: %d", nbytes_written);
738bool DreamFocuser::read_response()
740 int err_code = 0, nbytes_read = 0, z;
746 if ( (err_code =
tty_read(
PortFD, (
char *)¤tResponse,
sizeof(currentResponse), 5, &nbytes_read)) !=
TTY_OK)
749 LOGF_ERROR(
"TTY error detected: %s", err_msg);
752 LOGF_DEBUG(
"Response: %c, a=%hhu, b=%hhu, c=%hhu, d=%hhu ($%hhx), n=%hhu, z=%hhu", currentResponse.k, currentResponse.a,
753 currentResponse.b, currentResponse.c, currentResponse.d, currentResponse.d, currentResponse.addr, currentResponse.z);
755 if ( nbytes_read !=
sizeof(currentResponse) )
757 LOGF_ERROR(
"Number of bytes read: %d, expected: %d", nbytes_read,
sizeof(currentResponse));
761 z = calculate_checksum(currentResponse);
762 if ( z != currentResponse.z )
764 LOGF_ERROR(
"Response checksum in not correct %hhu, expected: %hhu", currentResponse.z, z );
768 if ( currentResponse.k ==
'!' )
770 LOG_ERROR(
"Focuser reported unrecognized command.");
774 if ( currentResponse.k ==
'?' )
776 LOG_ERROR(
"Focuser reported bad checksum.");
783bool DreamFocuser::dispatch_command(
char k, uint32_t l,
unsigned char addr)
786 if ( send_command(k, l, addr) )
788 if ( read_response() )
791 if ( currentResponse.k == k )
805 return (
char *)
"DreamFocuser";
void setDefaultBaudRate(BaudRate newRate)
setDefaultBaudRate Set default baud rate. The default baud rate is 9600 unless otherwise changed by t...
void setDefaultPort(const char *port)
setDefaultPort Set default port. Call this function in initProperties() of your driver if you want to...
virtual bool Handshake() override
Performs a device-specific handshake after a connection is established. This method should be overrid...
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Processes incoming new switch states from the client for this device. Handles updates to FocuserInter...
const char * getDefaultName() override
virtual bool initProperties() override
Initializes the default properties for the focuser device. Sets up standard INDI properties,...
virtual void TimerHit() override
Callback function to be called once SetTimer duration elapses.
virtual IPState MoveRelFocuser(FocusDirection dir, uint32_t ticks) override
MoveFocuser the focuser to an relative position.
virtual bool updateProperties() override
Updates the state and definition of properties based on the current connection status....
virtual IPState MoveAbsFocuser(uint32_t ticks) override
MoveFocuser the focuser to an absolute position.
virtual bool AbortFocuser() override
AbortFocuser all focus motion.
virtual bool SyncFocuser(uint32_t ticks) override
SyncFocuser Set current position to ticks without moving the focuser.
void setDefaultPollingPeriod(uint32_t msec)
setDefaultPollingPeriod Change the default polling period to call TimerHit() function in the driver.
void setVersion(uint16_t vMajor, uint16_t vMinor)
Set driver version information to be defined in DRIVER_INFO property as vMajor.vMinor.
virtual bool deleteProperty(const char *propertyName)
Delete a property and unregister it. It will also be deleted from all clients.
void defineProperty(INumberVectorProperty *property)
uint32_t getCurrentPollingPeriod() const
getCurrentPollingPeriod Return the current polling period.
int SetTimer(uint32_t ms)
Set a timer to call the function TimerHit after ms milliseconds.
INDI::PropertyNumber FocusRelPosNP
void SetCapability(uint32_t cap)
FI::SetCapability sets the focuser capabilities. All capabilities must be initialized.
INDI::PropertyNumber FocusMaxPosNP
INDI::PropertyNumber FocusAbsPosNP
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Processes incoming new switch states from the client for this device. Handles updates to FocuserInter...
virtual bool updateProperties() override
Updates the state and definition of properties based on the current connection status....
virtual bool initProperties() override
Initializes the default properties for the focuser device. Sets up standard INDI properties,...
Connection::Serial * serialConnection
virtual bool SetFocuserMaxPosition(uint32_t ticks) override
SetFocuserMaxPosition Update focuser maximum position. It only updates the PresetNP property limits.
void setState(IPState state)
void apply(const char *format,...) const ATTRIBUTE_FORMAT_PRINTF(2
bool isNameMatch(const char *otherName) const
void setPermission(IPerm permission)
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, double timeout, IPState state)
bool update(const ISState states[], const char *const names[], int n)
int findOnSwitchIndex() const
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, ISRule rule, double timeout, IPState state)
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
#define DREAMFOCUSER_STEP_SIZE
#define DREAMFOCUSER_ERROR_BUFFER
int tty_write(int fd, const char *buf, int nbytes, int *nbytes_written)
Writes a buffer to fd.
int tty_read(int fd, char *buf, int nbytes, int timeout, int *nbytes_read)
read buffer from terminal
void tty_error_msg(int err_code, char *err_msg, int err_msg_len)
Retrieve the tty error message.
Implementations for common driver routines.
#define LOGF_DEBUG(fmt,...)
#define LOG_ERROR(txt)
Shorter logging macros. In order to use these macros, the function (or method) "getDeviceName()" must...
#define LOGF_ERROR(fmt,...)
#define DEBUGF(priority, msg,...)