Instrument Neutral Distributed Interface INDI 2.2.5
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
42static std::unique_ptr<PegasusFlatMaster> flatmaster(new PegasusFlatMaster());
43
44
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 LightIntensityNP[0].setMin(0);
63 LightIntensityNP[0].setMax(100);
64 LightIntensityNP[0].setStep(1);
65
67
68 serialConnection = new Connection::Serial(this);
70 serialConnection->setPortMatchPattern("FlatMaster");
71 serialConnection->registerHandshake([&]()
72 {
73 return Ack();
74 });
75
76
77 registerConnection(serialConnection);
78 return true;
79}
80
82{
84
85 // Get Light box properties
87}
88
90{
92
93 if (isConnected())
94 {
95 defineProperty(&FirmwareTP);
96 }
97 else
98 {
99 deleteProperty(FirmwareTP.name);
100 }
101
103 return true;
104}
105
107{
108 return "Pegasus FlatMaster";
109}
110
111void PegasusFlatMaster::updateFirmwareVersion()
112{
113 char response[16] = {0};
114
115 if(sendCommand("V", response))
116 {
117 IUSaveText(&FirmwareT[0], response);
118 FirmwareTP.s = IPS_OK;
119 IDSetText(&FirmwareTP, nullptr);
120 }
121 else
122 {
123 FirmwareTP.s = IPS_ALERT;
124 LOG_ERROR("Error on updateFirmware.");
125 }
126}
127
128bool PegasusFlatMaster::Ack()
129{
130 PortFD = serialConnection->getPortFD();
131
132 char response[16] = {0};
133 if(sendCommand("#", response))
134 {
135 if(strstr("OK_FM", response) != nullptr)
136 {
137 updateFirmwareVersion();
138 return true;
139 }
140 }
141 else
142 {
143 LOG_ERROR("Ack failed.");
144 return false;
145 }
146
147 return false;
148}
149
151{
152 char response[16] = {0};
153 char cmd[16] = {0};
154
155 snprintf(cmd, 16, "E:%d", enable ? 1 : 0);
156
157 if(sendCommand(cmd, response))
158 {
159 if(strstr(cmd, response) != nullptr)
160 {
161 return true;
162 }
163 }
164 else
165 {
166 LOGF_ERROR("Error on EnableLightBox. %s", response);
167 return false;
168 }
169 return false;
170}
171
173{
174 if(LightSP[FLAT_LIGHT_ON].getState() != ISS_ON)
175 {
176 LOG_ERROR("You must set On the Flat Light first.");
177 return false;
178 }
179
180 char response[16] = {0};
181 char cmd[16] = {0};
182
183 uint16_t result = floor((100 - value - 0) * (255 - 20) / (100 - 0) + 20);
184
185 snprintf(cmd, 16, "L:%d", result);
186
187 if(sendCommand(cmd, response))
188 {
189 if(strstr(cmd, response) != nullptr)
190 {
191 return true;
192 }
193 }
194 else
195 {
196 LOGF_ERROR("Error on SetLightBoxBrightness. %s", response);
197 return false;
198 }
199 return false;
200}
201
202bool PegasusFlatMaster::ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
203{
204 if (LI::processNumber(dev, name, values, names, n))
205 return true;
206
207 return INDI::DefaultDevice::ISNewNumber(dev, name, values, names, n);
208}
209
210bool PegasusFlatMaster::ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
211{
212 if (dev != nullptr && strcmp(dev, getDeviceName()) == 0)
213 {
214 if (LI::processText(dev, name, texts, names, n))
215 return true;
216 }
217
218 return INDI::DefaultDevice::ISNewText(dev, name, texts, names, n);
219}
220
221bool PegasusFlatMaster::ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
222{
223 if (dev != nullptr && strcmp(dev, getDeviceName()) == 0)
224 {
225 if (LI::processSwitch(dev, name, states, names, n))
226 return true;
227 }
228
229 return INDI::DefaultDevice::ISNewSwitch(dev, name, states, names, n);
230}
231
233{
234 LI::snoop(root);
235
237}
238
245
246bool PegasusFlatMaster::sendCommand(const char *command, char *res)
247{
248 int nbytes_written = 0, nbytes_read = 0, rc = -1;
249 char errstr[MAXRBUF];
250
251 char cmd[7] = {0};
252 snprintf(cmd, 7, "%s\n", command);
253
254 LOGF_DEBUG("CMD <%#02X>", cmd[0]);
255
256 tcflush(PortFD, TCIOFLUSH);
257
258 if ((rc = tty_write(PortFD, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
259 {
260 tty_error_msg(rc, errstr, MAXRBUF);
261 LOGF_ERROR("command: %s error: %s.", cmd, errstr);
262 return false;
263 }
264
265 if ((rc = tty_read_section(PortFD, res, 0xA, 3, &nbytes_read)) != TTY_OK)
266 {
267 tty_error_msg(rc, errstr, MAXRBUF);
268 LOGF_ERROR("command: %s error: %s.", cmd, errstr);
269 return false;
270 }
271
272 // Get rid of 0xA
273 res[nbytes_read - 1] = 0;
274
275 if(res[nbytes_read - 2] == '\r')
276 res[nbytes_read - 2] = 0;
277
278 LOGF_DEBUG("RES <%s>", res);
279
280 tcflush(PortFD, TCIOFLUSH);
281
282 return true;
283}
void registerHandshake(std::function< bool()> callback)
registerHandshake Register a handshake function to be called once the initial connection to the devic...
The Serial class manages connection with serial devices including Bluetooth. Serial communication is ...
void setPortMatchPattern(const std::string &pattern)
setPortMatchPattern Set a regex pattern used to automatically select a serial port from the discovere...
void setDefaultBaudRate(BaudRate newRate)
setDefaultBaudRate Set default baud rate. The default baud rate is 9600 unless otherwise changed by t...
bool isConnected() const
const char * getDeviceName() const
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 setDriverInterface(uint32_t value)
setInterface Set driver interface. By default the driver interface is set to GENERAL_DEVICE....
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()
Initialize 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.
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
Process the client newSwitch command.
void initProperties(const char *group, uint32_t capabilities)
Initialize light box properties. It is recommended to call this function within initProperties() of y...
void ISGetProperties(const char *deviceName)
isGetLightBoxProperties Get light box properties
INDI::PropertyNumber LightIntensityNP
bool processSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Process light box switch properties.
bool processText(const char *dev, const char *name, char *texts[], char *names[], int n)
Process light box text properties.
bool processNumber(const char *dev, const char *name, double values[], char *names[], int n)
Process light box number 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 implemented in the child class, if supported.
virtual bool initProperties() override
Initialize 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 implemented 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:148
@ ISS_ON
Definition indiapi.h:150
@ 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
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:509
void IUSaveText(IText *tp, const char *newtext)
Function to reliably save new text in a IText.
Definition indidevapi.c:44
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:416
#define MAXRBUF
Definition indidriver.c:52
void IDSetText(const ITextVectorProperty *tvp, const char *fmt,...)
#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
uint8_t cmd[4]
Definition pwc-ioctl.h:2
char name[MAXINDINAME]
Definition indiapi.h:248