Instrument Neutral Distributed Interface INDI 2.2.5
ioptron_wheel.cpp
Go to the documentation of this file.
1/*******************************************************************************
2 Copyright(c) 2024 Joe Zhou. All rights reserved.
3
4 iOptron 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 "ioptron_wheel.h"
22
23#include "indicom.h"
25#include <cstring>
26#include <memory>
27#include <termios.h>
28
29#define iEFW_TIMEOUT 4
30
31/*
32command :
33:WMnn# Response: 1
34get position ,nn filter num。
35
36:WP# Response: nn# or -1#
37get curr position,nn =curr position,if is moving,return -1。
38
39:WOnnsnnnnn# Response: 1
40set offset。nn =filter num , snnnnn=offset
41
42:WFnn# Response: snnnnn#
43get offset 。nn = filter num , snnnnn=offset
44
45":DeviceInfo#" Response: "nnnnnnnnnnnn#"
46This command includes 12 digits.
47The 7th and 8th digit means model of filter wheel.
48Model number 99 is iEFW-15, 98 is iEFW18
49
50:FW1# Response: nnnnnnnnnnnn#
51get firmware version
52
53
54*/
55
56
57static std::unique_ptr<iEFW> iefw_wheel(new iEFW());
58
64
66{
67 return "iOptron Wheel";
68}
69
71{
73 // serialConnection->setDefaultPort("/dev/ttyUSB3");
75 FilterSlotNP[0].setMin(1);
76 FilterSlotNP[0].setMax(8);
77 FirmwareTP[0].fill("FIRMWARE", "Firmware", "240101240101");
78 FirmwareTP.fill(getDeviceName(), "FIRMWARE_ID", "iEFW Firmware", FILTER_TAB, IP_RO, 60, IPS_IDLE);
79 WheelIDTP[0].fill("MODEL", "Model", "iEFW");
80 WheelIDTP.fill(getDeviceName(), "MODEL_ID", "iEFW Model", FILTER_TAB, IP_RO, 60, IPS_IDLE);
81 return true;
82}
83
85{
87
88 if (isConnected())
89 {
90 defineProperty(HomeSP);
93 bool rc1 = getiEFWInfo();
94 bool rc2 = getiEFWfirmwareInfo();
96 return (rc1 && rc2);
97 }
98 else
99 {
100 deleteProperty(HomeSP);
103 }
104 return true;
105}
106
107bool iEFW::ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
108{
109 if (dev != nullptr && strcmp(dev, getDeviceName()) == 0)
110 {
111 if (HomeSP.isNameMatch(name))
112 {
113 if (getiEFWID())
114 {
115 LOG_INFO("Filter is at home position");
116 HomeSP.setState(IPS_OK);
117 HomeSP.apply();
118 }
119 else
120 HomeSP.setState(IPS_ALERT);
121 HomeSP.apply();
122 return true;
123 }
124 }
125
126 return INDI::FilterWheel::ISNewSwitch(dev, name, states, names, n);
127}
128
130{
131
132 return getiEFWID();
133}
134
136bool iEFW::getiEFWInfo()
137{
138 int nbytes_written = 0, nbytes_read = 0, rc = -1;
139 char resp[16];
140 int iefwpos, iefwmodel, iefwlast;
141 sleep(2);
142 tcflush(PortFD, TCIOFLUSH);
143 if ( (rc = tty_write(PortFD, ":DeviceInfo#", strlen(":DeviceInfo#"), &nbytes_written)) != TTY_OK)
144 {
145 char errstr[MAXRBUF] = {0};
146 tty_error_msg(rc, errstr, MAXRBUF);
147 LOGF_ERROR( "Init send iEFW deviceinfo error: %s.", errstr);
148 return false;
149 };
150
151 if ( (rc = tty_read_section(PortFD, resp, '#', iEFW_TIMEOUT * 2, &nbytes_read)) != TTY_OK)
152 {
153 char errstr[MAXRBUF] = {0};
154 tty_error_msg(rc, errstr, MAXRBUF);
155 LOGF_ERROR( "Init read iEFW deviceinfo error: %s.", errstr);
156 return false;
157 };
158 tcflush(PortFD, TCIOFLUSH);
159 resp[nbytes_read] = '\0';
160 sscanf(resp, "%6d%2d%4d", &iefwpos, &iefwmodel, &iefwlast);
161 if ((iefwmodel == 98) || (iefwmodel == 99))
162 {
163 if (iefwmodel == 99)
164 {
165 FilterSlotNP[0].setMax(5);
167 WheelIDTP[0].setText("iEFW-15");
169 };
170 if (iefwmodel == 98)
171 {
172 FilterSlotNP[0].setMax(8);
174 WheelIDTP[0].setText("iEFW-18");
176
177 };
178 return true;
179 }
180 else
181 {
182 LOGF_ERROR( "iEFW getinfo Response: %s", resp);
183 return false;
184 }
185
186 return true;
187}
188
191bool iEFW::getiEFWfirmwareInfo()
192{
193 int nbytes_written = 0, nbytes_read = 0, rc = -1;
194 char errstr[MAXRBUF];
195 char resp[16] = {0};
196 char iefwfirminfo[16] = {0};
197 tcflush(PortFD, TCIOFLUSH);
198 if ( (rc = tty_write(PortFD, ":FW1#", 5, &nbytes_written)) != TTY_OK)
199 {
200 tty_error_msg(rc, errstr, MAXRBUF);
201 LOGF_ERROR( "get iEFW FiremwareInfo error: %s.", errstr);
202 }
203 if ( (rc = tty_read_section(PortFD, resp, '#', iEFW_TIMEOUT, &nbytes_read)) != TTY_OK)
204 {
205 tty_error_msg(rc, errstr, MAXRBUF);
206 LOGF_ERROR( "get iEFW FirmwareInfo error: %s.", errstr);
207 return false;
208 }
209 tcflush(PortFD, TCIOFLUSH);
210 resp[nbytes_read] = '\0';
211 sscanf(resp, "%12s", iefwfirminfo);
213 FirmwareTP[0].setText(iefwfirminfo);
215 LOGF_DEBUG("Success, response from iEFW is : %s", iefwfirminfo);
216 return true;
217}
218
220{
221 int nbytes_written = 0, nbytes_read = 0, rc = -1;
222 char errstr[MAXRBUF];
223 char resp[16] = {0};
224 int iefwpos = 1;
225 tcflush(PortFD, TCIOFLUSH);
226 if ( (rc = tty_write(PortFD, ":WP#", 4, &nbytes_written)) != TTY_OK)
227 {
228 tty_error_msg(rc, errstr, MAXRBUF);
229 LOGF_ERROR( "send iEFW filter pos Info error: %s.", errstr);
230 }
231 if ( (rc = tty_read_section(PortFD, resp, '#', iEFW_TIMEOUT, &nbytes_read)) != TTY_OK)
232 {
233 tty_error_msg(rc, errstr, MAXRBUF);
234 LOGF_ERROR( "read iEFW filter pos Info error: %s.", errstr);
235 return false;
236 }
237 tcflush(PortFD, TCIOFLUSH);
238 resp[nbytes_read] = '\0';
239 LOGF_DEBUG("Success, response from iEFW is : %s", resp);
240 rc = sscanf(resp, "%2d", &iefwpos);
241 if (rc > 0)
242 {
243 if (iefwpos >= 0)
244 {
245 CurrentFilter = iefwpos + 1;
246 FilterSlotNP[0].setValue(CurrentFilter);
248 return CurrentFilter;
249 }
250 else
251 return -1;
252 }
253 else
254 return 999;
255
256}
257
258
259bool iEFW::getiEFWID()
260{
261 return getiEFWInfo();
262}
263
265{
266 int nbytes_written = 0, rc = -1;
267 char errstr[MAXRBUF];
268 // char resp[16] = {0};
269 // char iefwposinfo[16] = {0};
270 int iefwpos = -1;
271 char cmd[7] = {0};
272 if (CurrentFilter == f)
273 {
275 return true;
276 }
277 f = f - 1;
278
279 if (f < 0 || f > (FilterSlotNP[0].getMax() - 1))
280 return false;
281
282 tcflush(PortFD, TCIOFLUSH);
283 snprintf(cmd, 7, ":WM0%d#", f);
284 if ( (rc = tty_write(PortFD, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
285 {
286 tty_error_msg(rc, errstr, MAXRBUF);
287 LOGF_ERROR( "select iEFW send pos Info error: %s.", errstr);
288 }
289 tcflush(PortFD, TCIOFLUSH);
290 // check current position -1 is moving
291 do
292 {
293 usleep(100 * 1000);
294 iefwpos = getFilterPos();
295 }
296 while (iefwpos == -1);
297 // return current position to indi
298 CurrentFilter = f + 1;
301 FilterSlotNP.apply("Selected filter position reached");
302 LOGF_DEBUG("CurrentFilter set to %d", CurrentFilter);
303 return true;
304}
305
307{
308 return CurrentFilter;
309}
void setDefaultBaudRate(BaudRate newRate)
setDefaultBaudRate Set default baud rate. The default baud rate is 9600 unless otherwise changed by t...
bool isConnected() const
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)
INDI::PropertyNumber 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.
Connection::Serial * serialConnection
virtual bool initProperties() override
Initialize 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.
void setState(IPState state)
void apply(const char *format,...) const ATTRIBUTE_FORMAT_PRINTF(2
bool isNameMatch(const char *otherName) const
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, double timeout, IPState state)
INDI::PropertyText WheelIDTP
const char * getDefaultName() override
bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
INDI::PropertyText FirmwareTP
bool Handshake() override
perform handshake with device to check communication
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
int getFilterPos()
int QueryFilter() override
Return current filter position.
bool SelectFilter(int) override
Select a new filter position.
bool initProperties() override
Initialize properties initial state and value. The child class must implement this function.
const char * FILTER_TAB
FILTER_TAB Where all the properties for filter wheels are located.
ISState
Switch state.
Definition indiapi.h:148
@ IP_RO
Definition indiapi.h:182
@ IPS_ALERT
Definition indiapi.h:162
@ IPS_IDLE
Definition indiapi.h:159
@ IPS_OK
Definition indiapi.h:160
int tty_read_section(int fd, char *buf, char stop_char, int timeout, int *nbytes_read)
read buffer from terminal with a delimiter
Definition indicom.c:653
int tty_write(int fd, const char *buf, int nbytes, int *nbytes_written)
Writes a buffer to fd.
Definition indicom.c:418
void tty_error_msg(int err_code, char *err_msg, int err_msg_len)
Retrieve the tty error message.
Definition indicom.c:1243
Implementations for common driver routines.
@ TTY_OK
Definition indicom.h:54
#define MAXRBUF
Definition indidriver.c:52
#define LOGF_DEBUG(fmt,...)
Definition indilogger.h:83
#define LOGF_ERROR(fmt,...)
Definition indilogger.h:80
#define LOG_INFO(txt)
Definition indilogger.h:74
#define getDeviceName
#define iEFW_TIMEOUT
uint8_t cmd[4]
Definition pwc-ioctl.h:2