Instrument Neutral Distributed Interface INDI  2.0.2
pegasus_flatmaster.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2  Copyright(c) 2021 Chrysikos Efstathios. All rights reserved.
3 
4  Pegasus FlatMaster
5 
6  2022-06-07 Jasem Mutlaq: Use lightbox interface properly.
7 
8  This program is free software; you can redistribute it and/or modify it
9  under the terms of the GNU General Public License as published by the Free
10  Software Foundation; either version 2 of the License, or (at your option)
11  any later version.
12 
13  This program is distributed in the hope that it will be useful, but WITHOUT
14  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16  more details.
17 
18  You should have received a copy of the GNU Library General Public License
19  along with this library; see the file COPYING.LIB. If not, write to
20  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  Boston, MA 02110-1301, USA.
22 
23  The full GNU General Public License is included in this distribution in the
24  file called LICENSE.
25 *******************************************************************************/
26 
27 #include "pegasus_flatmaster.h"
28 
29 #include "indicom.h"
31 
32 #include <cerrno>
33 #include <cstring>
34 #include <memory>
35 #include <termios.h>
36 #include <unistd.h>
37 #include <inttypes.h>
38 #include <sys/ioctl.h>
39 #include <math.h>
40 
41 
42 static std::unique_ptr<PegasusFlatMaster> flatmaster(new PegasusFlatMaster());
43 
44 
46 {
47  setVersion(1, 2);
48 }
49 
51 {
53 
54  // Firmware version
55  IUFillText(&FirmwareT[0], "Version", "Version", nullptr);
56  IUFillTextVector(&FirmwareTP, FirmwareT, 1, getDeviceName(), "Firmware", "Firmware", MAIN_CONTROL_TAB, IP_RO, 60, IPS_IDLE);
57 
59 
61 
62  LightIntensityN[0].min = 0;
63  LightIntensityN[0].max = 100;
64  LightIntensityN[0].step = 1;
65 
67 
68  serialConnection = new Connection::Serial(this);
70  serialConnection->registerHandshake([&]()
71  {
72  return Ack();
73  });
74 
75 
76  registerConnection(serialConnection);
77  return true;
78 }
79 
81 {
83 
84  // Get Light box properties
86 }
87 
89 {
91 
92  if (isConnected())
93  {
96  defineProperty(&FirmwareTP);
97  }
98  else
99  {
102  deleteProperty(FirmwareTP.name);
103  }
104 
106  return true;
107 }
108 
110 {
111  return "Pegasus FlatMaster";
112 }
113 
114 void PegasusFlatMaster::updateFirmwareVersion()
115 {
116  char response[16] = {0};
117 
118  if(sendCommand("V", response))
119  {
120  IUSaveText(&FirmwareT[0], response);
121  FirmwareTP.s = IPS_OK;
122  IDSetText(&FirmwareTP, nullptr);
123  }
124  else
125  {
126  FirmwareTP.s = IPS_ALERT;
127  LOG_ERROR("Error on updateFirmware.");
128  }
129 }
130 
131 bool PegasusFlatMaster::Ack()
132 {
133  PortFD = serialConnection->getPortFD();
134 
135  char response[16] = {0};
136  if(sendCommand("#", response))
137  {
138  if(strstr("OK_FM", response) != nullptr)
139  {
140  updateFirmwareVersion();
141  return true;
142  }
143  }
144  else
145  {
146  LOG_ERROR("Ack failed.");
147  return false;
148  }
149 
150  return false;
151 }
152 
154 {
155  char response[16] = {0};
156  char cmd[16] = {0};
157 
158  snprintf(cmd, 16, "E:%d", enable ? 1 : 0);
159 
160  if(sendCommand(cmd, response))
161  {
162  if(strstr(cmd, response) != nullptr)
163  {
164  return true;
165  }
166  }
167  else
168  {
169  LOGF_ERROR("Error on EnableLightBox. %s", response);
170  return false;
171  }
172  return false;
173 }
174 
176 {
177  if(LightS[FLAT_LIGHT_ON].s != ISS_ON)
178  {
179  LOG_ERROR("You must set On the Flat Light first.");
180  return false;
181  }
182 
183  char response[16] = {0};
184  char cmd[16] = {0};
185 
186  uint16_t result = floor((100 - value - 0) * (255 - 20) / (100 - 0) + 20);
187 
188  snprintf(cmd, 16, "L:%d", result);
189 
190  if(sendCommand(cmd, response))
191  {
192  if(strstr(cmd, response) != nullptr)
193  {
194  return true;
195  }
196  }
197  else
198  {
199  LOGF_ERROR("Error on SetLightBoxBrightness. %s", response);
200  return false;
201  }
202  return false;
203 }
204 
205 bool PegasusFlatMaster::ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
206 {
207  if (processLightBoxNumber(dev, name, values, names, n))
208  return true;
209 
210  return INDI::DefaultDevice::ISNewNumber(dev, name, values, names, n);
211 }
212 
213 bool PegasusFlatMaster::ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
214 {
215  if (dev != nullptr && strcmp(dev, getDeviceName()) == 0)
216  {
217  if (processLightBoxText(dev, name, texts, names, n))
218  return true;
219  }
220 
221  return INDI::DefaultDevice::ISNewText(dev, name, texts, names, n);
222 }
223 
224 bool PegasusFlatMaster::ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
225 {
226  if (dev != nullptr && strcmp(dev, getDeviceName()) == 0)
227  {
228  if (processLightBoxSwitch(dev, name, states, names, n))
229  return true;
230  }
231 
232  return INDI::DefaultDevice::ISNewSwitch(dev, name, states, names, n);
233 }
234 
236 {
237  snoopLightBox(root);
238 
240 }
241 
243 {
245 
246  return saveLightBoxConfigItems(fp);
247 }
248 
249 bool PegasusFlatMaster::sendCommand(const char *command, char *res)
250 {
251  int nbytes_written = 0, nbytes_read = 0, rc = -1;
252  char errstr[MAXRBUF];
253 
254  char cmd[7] = {0};
255  snprintf(cmd, 7, "%s\n", command);
256 
257  LOGF_DEBUG("CMD <%#02X>", cmd[0]);
258 
259  tcflush(PortFD, TCIOFLUSH);
260 
261  if ((rc = tty_write(PortFD, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
262  {
263  tty_error_msg(rc, errstr, MAXRBUF);
264  LOGF_ERROR("command: %s error: %s.", cmd, errstr);
265  return false;
266  }
267 
268  if ((rc = tty_read_section(PortFD, res, 0xA, 3, &nbytes_read)) != TTY_OK)
269  {
270  tty_error_msg(rc, errstr, MAXRBUF);
271  LOGF_ERROR("command: %s error: %s.", cmd, errstr);
272  return false;
273  }
274 
275  // Get rid of 0xA
276  res[nbytes_read - 1] = 0;
277 
278  if(res[nbytes_read - 2] == '\r')
279  res[nbytes_read - 2] = 0;
280 
281  LOGF_DEBUG("RES <%s>", res);
282 
283  tcflush(PortFD, TCIOFLUSH);
284 
285  return true;
286 }
void registerHandshake(std::function< bool()> callback)
registerHandshake Register a handshake function to be called once the intial connection to the device...
The Serial class manages connection with serial devices including Bluetooth. Serial communication is ...
void setDefaultBaudRate(BaudRate newRate)
setDefaultBaudRate Set default baud rate. The default baud rate is 9600 unless otherwise changed by t...
bool isConnected() const
Definition: basedevice.cpp:520
const char * getDeviceName() const
Definition: basedevice.cpp:821
virtual bool updateProperties()
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)
Process the client newSwitch command.
void registerConnection(Connection::Interface *newConnection)
registerConnection Add new connection plugin to the existing connection pool. The connection type sha...
virtual void ISGetProperties(const char *dev)
define the driver's properties to the client. Usually, only a minimum set of properties are defined t...
virtual bool ISSnoopDevice(XMLEle *root)
Process a snoop event from INDI server. This function is called when a snooped property is updated in...
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)
virtual bool saveConfigItems(FILE *fp)
saveConfigItems Save specific properties in the provide config file handler. Child class usually over...
virtual bool initProperties()
Initilize properties initial state and value. The child class must implement this function.
void addAuxControls()
Add Debug, Simulation, and Configuration options to the driver.
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
Process the client newNumber command.
void setDriverInterface(uint16_t value)
setInterface Set driver interface. By default the driver interface is set to GENERAL_DEVICE....
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
Process the client newSwitch command.
INumberVectorProperty LightIntensityNP
bool processLightBoxNumber(const char *dev, const char *name, double values[], char *names[], int n)
Process light box number properties.
ISwitchVectorProperty LightSP
bool processLightBoxSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Process light box switch properties.
void initLightBoxProperties(const char *deviceName, const char *groupNam)
Initilize light box properties. It is recommended to call this function within initProperties() of yo...
bool processLightBoxText(const char *dev, const char *name, char *texts[], char *names[], int n)
Process light box text properties.
void isGetLightBoxProperties(const char *deviceName)
isGetLightBoxProperties Get light box properties
Provides interface to implement controllable light box/switch device.
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
virtual bool SetLightBoxBrightness(uint16_t value) override
setBrightness Set light level. Must be impelemented in the child class, if supported.
virtual bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Save specific properties in the provide config file handler. Child class usually over...
void ISGetProperties(const char *dev) override
define the driver's properties to the client. Usually, only a minimum set of properties are defined t...
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
virtual bool EnableLightBox(bool enable) override
EnableLightBox Turn on/off on a light box. Must be impelemented in the child class.
virtual bool ISSnoopDevice(XMLEle *root) override
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) override
Process the client newSwitch command.
const char * getDefaultName() override
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_ON
Definition: indiapi.h:152
@ IP_RO
Definition: indiapi.h:184
@ IPS_ALERT
Definition: indiapi.h:164
@ IPS_IDLE
Definition: indiapi.h:161
@ IPS_OK
Definition: indiapi.h:162
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:566
int tty_write(int fd, const char *buf, int nbytes, int *nbytes_written)
Writes a buffer to fd.
Definition: indicom.c:424
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
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: indidevapi.c:291
void IUSaveText(IText *tp, const char *newtext)
Function to reliably save new text in a IText.
Definition: indidevapi.c:36
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: indidevapi.c:198
void IDSetText(const ITextVectorProperty *tvp, const char *fmt,...)
Definition: indidriver.c:1191
#define LOGF_DEBUG(fmt,...)
Definition: indilogger.h:83
#define LOG_ERROR(txt)
Shorter logging macros. In order to use these macros, the function (or method) "getDeviceName()" must...
Definition: indilogger.h:72
#define LOGF_ERROR(fmt,...)
Definition: indilogger.h:80
#define MAXRBUF
Definition: indiserver.cpp:102
__u8 cmd[4]
Definition: pwc-ioctl.h:2
char name[MAXINDINAME]
Definition: indiapi.h:323
char name[MAXINDINAME]
Definition: indiapi.h:371
char name[MAXINDINAME]
Definition: indiapi.h:250