Instrument Neutral Distributed Interface INDI  2.0.2
trutech_wheel.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2  Copyright(c) 2017 Jasem Mutlaq. All rights reserved.
3 
4  Tru Technology Filter Wheel
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Library General Public
8  License version 2 as published by the Free Software Foundation.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Library General Public License for more details.
14 
15  You should have received a copy of the GNU Library General Public License
16  along with this library; see the file COPYING.LIB. If not, write to
17  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  Boston, MA 02110-1301, USA.
19 *******************************************************************************/
20 
21 #include "trutech_wheel.h"
22 
23 #include "indicom.h"
24 
25 #include <cstring>
26 #include <memory>
27 #include <termios.h>
28 
29 #define BUF_SIZE 5
30 #define CMD_SIZE 4
31 
32 const uint8_t COMM_INIT = 0xA5;
33 const uint8_t COMM_FILL = 0x20;
34 
35 static std::unique_ptr<TruTech> tru_wheel(new TruTech());
36 
38 {
39  setVersion(1, 0);
41 }
42 
44 {
45  return "TruTech Wheel";
46 }
47 
49 {
51 
52  IUFillSwitch(&HomeS[0], "Find", "Find", ISS_OFF);
53  IUFillSwitchVector(&HomeSP, HomeS, 1, getDeviceName(), "HOME", "Home", MAIN_CONTROL_TAB, IP_RW, ISR_1OFMANY, 60,
54  IPS_IDLE);
55 
57 
58  return true;
59 }
60 
62 {
64 
65  if (isConnected())
66  defineProperty(&HomeSP);
67  else
68  deleteProperty(HomeSP.name);
69 
70  return true;
71 }
72 
73 bool TruTech::ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
74 {
75  if (dev != nullptr && strcmp(dev, getDeviceName()) == 0)
76  {
77  if (!strcmp(HomeSP.name, name))
78  {
79  if (home())
80  {
81  LOG_INFO("Filter set to home position.");
82  HomeSP.s = IPS_OK;
84  IDSetNumber(&FilterSlotNP, nullptr);
85  }
86  else
87  HomeSP.s = IPS_ALERT;
88  IDSetSwitch(&HomeSP, nullptr);
89  return true;
90  }
91  }
92 
93  return INDI::FilterWheel::ISNewSwitch(dev, name, states, names, n);
94 }
95 
97 {
98  return home();
99 }
100 
101 bool TruTech::home()
102 {
103  int rc = 0, nbytes_written = 0, nbytes_read = 0;
104  uint8_t type = 0x03;
105  uint8_t chksum = COMM_INIT + type + COMM_FILL;
106  char filter_command[BUF_SIZE] = {0};
107  snprintf(filter_command, BUF_SIZE, "%c%c%c%c", COMM_INIT, type, COMM_FILL, chksum);
108 
109  LOGF_DEBUG("CMD: %#02X %#02X %#02X %#02X", COMM_INIT, type, COMM_FILL, chksum);
110 
111  tcflush(PortFD, TCIOFLUSH);
112 
113  if ( (rc = tty_write(PortFD, filter_command, CMD_SIZE, &nbytes_written)) != TTY_OK)
114  {
115  char error_message[ERRMSG_SIZE];
116  tty_error_msg(rc, error_message, ERRMSG_SIZE);
117  LOGF_ERROR("Sending command Home to filter failed: %s", error_message);
118  }
119 
120  char filter_response[BUF_SIZE] = {0};
121 
122  if ( (rc = tty_read(PortFD, filter_response, CMD_SIZE, 3, &nbytes_read)) != TTY_OK)
123  {
124  char error_message[ERRMSG_SIZE];
125  tty_error_msg(rc, error_message, ERRMSG_SIZE);
126  LOGF_ERROR("Error receiving response from filter: %s", error_message);
127  }
128 
129  if (static_cast<uint8_t>(filter_response[0]) == COMM_INIT)
130  {
131  CurrentFilter = 1;
132  FilterSlotN[0].value = 1;
133  FilterSlotN[0].min = 1;
134  FilterSlotN[0].max = filter_response[2] - 0x30;
135  }
136 
137  return true;
138 }
139 
141 {
142  TargetFilter = f;
143 
144  int rc = 0, nbytes_written = 0;
145  char filter_command[BUF_SIZE] = {0};
146  uint8_t type = 0x01;
147  uint8_t chksum = COMM_INIT + type + static_cast<uint8_t>(f);
148  snprintf(filter_command, BUF_SIZE, "%c%c%c%c", COMM_INIT, type, f, chksum);
149 
150  LOGF_DEBUG("CMD: %#02X %#02X %#02X %#02X", COMM_INIT, type, f, chksum);
151 
152  tcflush(PortFD, TCIOFLUSH);
153 
154  if ((rc = tty_write(PortFD, filter_command, CMD_SIZE, &nbytes_written)) != TTY_OK)
155  {
156  char error_message[ERRMSG_SIZE];
157  tty_error_msg(rc, error_message, ERRMSG_SIZE);
158 
159  LOGF_ERROR("Sending command select filter failed: %s", error_message);
160  return false;
161  }
162 
163  return true;
164 }
165 
167 {
168  return CurrentFilter;
169 }
170 
172 {
173  if (FilterSlotNP.s == IPS_BUSY)
174  {
175  int rc = 0, nbytes_written = 0, nbytes_read = 0;
176  uint8_t type = 0x02;
177  uint8_t chksum = COMM_INIT + type + COMM_FILL;
178  char filter_command[BUF_SIZE] = {0};
179  snprintf(filter_command, BUF_SIZE, "%c%c%c%c", COMM_INIT, type, COMM_FILL, chksum);
180 
181  LOGF_DEBUG("CMD: %#02X %#02X %#02X %#02X", COMM_INIT, type, COMM_FILL, chksum);
182 
183  tcflush(PortFD, TCIOFLUSH);
184 
185  if ( (rc = tty_write(PortFD, filter_command, CMD_SIZE, &nbytes_written)) != TTY_OK)
186  {
187  char error_message[ERRMSG_SIZE];
188  tty_error_msg(rc, error_message, ERRMSG_SIZE);
189  LOGF_WARN("Sending filter query failed: %s", error_message);
190  }
191  else
192  {
193  char filter_response[BUF_SIZE] = {0};
194 
195  if ( (rc = tty_read(PortFD, filter_response, CMD_SIZE, 3, &nbytes_read)) != TTY_OK)
196  {
197  char error_message[ERRMSG_SIZE];
198  tty_error_msg(rc, error_message, ERRMSG_SIZE);
199  LOGF_ERROR("Error receiving response from filter: %s", error_message);
200  }
201 
202  if (static_cast<uint8_t>(filter_response[0]) == COMM_INIT)
203  {
204  // If filter finished moving
205  if (filter_response[2] > 0x30)
206  {
207  CurrentFilter = filter_response[2] - 0x30;
209  }
210  }
211  }
212  }
213 
215 }
bool isConnected() const
Definition: basedevice.cpp:520
const char * getDeviceName() const
Definition: basedevice.cpp:821
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.
void addAuxControls()
Add Debug, Simulation, and Configuration options to the driver.
int SetTimer(uint32_t ms)
Set a timer to call the function TimerHit after ms milliseconds.
INumberVectorProperty FilterSlotNP
void SelectFilterDone(int newpos)
The child class calls this function when the hardware successfully finished selecting a new filter wh...
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
virtual bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
void setFilterConnection(const uint8_t &value)
setFilterConnection Set Filter connection mode. Child class should call this in the constructor befor...
int PortFD
For Serial & TCP connections.
int QueryFilter() override
Return current filter position.
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
bool SelectFilter(int) override
Select a new filter position.
void TimerHit() override
Callback function to be called once SetTimer duration elapses.
const char * getDefaultName() override
bool Handshake() override
perform handshake with device to check communication
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
ISState
Switch state.
Definition: indiapi.h:150
@ ISS_OFF
Definition: indiapi.h:151
@ IP_RW
Definition: indiapi.h:186
@ IPS_BUSY
Definition: indiapi.h:163
@ IPS_ALERT
Definition: indiapi.h:164
@ IPS_IDLE
Definition: indiapi.h:161
@ IPS_OK
Definition: indiapi.h:162
@ ISR_1OFMANY
Definition: indiapi.h:173
int tty_write(int fd, const char *buf, int nbytes, int *nbytes_written)
Writes a buffer to fd.
Definition: indicom.c:424
int tty_read(int fd, char *buf, int nbytes, int timeout, int *nbytes_read)
read buffer from terminal
Definition: indicom.c:482
void tty_error_msg(int err_code, char *err_msg, int err_msg_len)
Retrieve the tty error message.
Definition: indicom.c:1167
Implementations for common driver routines.
@ TTY_OK
Definition: indicom.h:150
#define ERRMSG_SIZE
Definition: indicom.h:49
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:158
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:235
void IDSetNumber(const INumberVectorProperty *nvp, const char *fmt,...)
Definition: indidriver.c:1211
void IDSetSwitch(const ISwitchVectorProperty *svp, const char *fmt,...)
Definition: indidriver.c:1231
#define LOGF_WARN(fmt,...)
Definition: indilogger.h:81
#define LOGF_DEBUG(fmt,...)
Definition: indilogger.h:83
#define LOGF_ERROR(fmt,...)
Definition: indilogger.h:80
#define LOG_INFO(txt)
Definition: indilogger.h:74
__le16 type
Definition: pwc-ioctl.h:0
char name[MAXINDINAME]
Definition: indiapi.h:371
#define CMD_SIZE
#define BUF_SIZE
const uint8_t COMM_INIT
const uint8_t COMM_FILL