Instrument Neutral Distributed Interface INDI 2.2.5
celestron_dewpower_auxproto.cpp
Go to the documentation of this file.
1/*
2 Celestron Aux Command
3
4 Copyright (C) 2020 Paweł T. Jochym
5 Copyright (C) 2020 Fabrizio Pollastri
6 Copyright (C) 2021 Jasem Mutlaq
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2.1 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public
19 License along with this library; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
22*/
23
25
26#include <indilogger.h>
27#include <math.h>
28#include <string.h>
29#include <unistd.h>
30#include <stdio.h>
31
32#define BUFFER_SIZE 512
33int MAX_CMD_LEN = 32;
34
35uint8_t AUXCommand::DEBUG_LEVEL = 0;
36char AUXCommand::DEVICE_NAME[64] = {0};
40
44void logBytes(unsigned char *buf, int n, const char *deviceName, uint32_t debugLevel)
45{
46 char hex_buffer[BUFFER_SIZE] = {0};
47 for (int i = 0; i < n; i++)
48 sprintf(hex_buffer + 3 * i, "%02X ", buf[i]);
49
50 if (n > 0)
51 hex_buffer[3 * n - 1] = '\0';
52
53 DEBUGFDEVICE(deviceName, debugLevel, "[%s]", hex_buffer);
54}
55
60{
61 char hex_buffer[BUFFER_SIZE] = {0}, part1[BUFFER_SIZE] = {0}, part2[BUFFER_SIZE] = {0}, part3[BUFFER_SIZE] = {0};
62 for (size_t i = 0; i < m_Data.size(); i++)
63 sprintf(hex_buffer + 3 * i, "%02X ", m_Data[i]);
64
65 if (m_Data.size() > 0)
66 hex_buffer[3 * m_Data.size() - 1] = '\0';
67
68 const char * c = commandName(m_Command);
69 const char * s = moduleName(m_Source);
70 const char * d = moduleName(m_Destination);
71
72 if (c != nullptr)
73 snprintf(part1, BUFFER_SIZE, "<%12s>", c);
74 else
75 snprintf(part1, BUFFER_SIZE, "<%02x>", m_Command);
76
77 if (s != nullptr)
78 snprintf(part2, BUFFER_SIZE, "%5s ->", s);
79 else
80 snprintf(part2, BUFFER_SIZE, "%02x ->", m_Source);
81
82 if (s != nullptr)
83 snprintf(part3, BUFFER_SIZE, "%5s", d);
84 else
85 snprintf(part3, BUFFER_SIZE, "%02x", m_Destination);
86
87 if (m_Data.size() > 0)
88 DEBUGFDEVICE(DEVICE_NAME, DEBUG_LEVEL, "RES %s%s%s [%s]", part1, part2, part3, hex_buffer);
89 else
90 DEBUGFDEVICE(DEVICE_NAME, DEBUG_LEVEL, "RES %s%s%s", part1, part2, part3);
91}
92
97{
98 char hex_buffer[BUFFER_SIZE] = {0}, part1[BUFFER_SIZE] = {0}, part2[BUFFER_SIZE] = {0}, part3[BUFFER_SIZE] = {0};
99 for (size_t i = 0; i < m_Data.size(); i++)
100 sprintf(hex_buffer + 3 * i, "%02X ", m_Data[i]);
101
102 if (m_Data.size() > 0)
103 hex_buffer[3 * m_Data.size() - 1] = '\0';
104
105 const char * c = commandName(m_Command);
106 const char * s = moduleName(m_Source);
107 const char * d = moduleName(m_Destination);
108
109 if (c != nullptr)
110 snprintf(part1, BUFFER_SIZE, "<%12s>", c);
111 else
112 snprintf(part1, BUFFER_SIZE, "<%02x>", m_Command);
113
114 if (s != nullptr)
115 snprintf(part2, BUFFER_SIZE, "%5s ->", s);
116 else
117 snprintf(part2, BUFFER_SIZE, "%02x ->", m_Source);
118
119 if (s != nullptr)
120 snprintf(part3, BUFFER_SIZE, "%5s", d);
121 else
122 snprintf(part3, BUFFER_SIZE, "%02x", m_Destination);
123
124 if (m_Data.size() > 0)
125 DEBUGFDEVICE(DEVICE_NAME, DEBUG_LEVEL, "CMD %s%s%s [%s]", part1, part2, part3, hex_buffer);
126 else
127 DEBUGFDEVICE(DEVICE_NAME, DEBUG_LEVEL, "CMD %s%s%s", part1, part2, part3);
128}
129
133void AUXCommand::setDebugInfo(const char *deviceName, uint8_t debugLevel)
134{
135 snprintf(DEVICE_NAME, sizeof(DEVICE_NAME), "%s", deviceName);
136 DEBUG_LEVEL = debugLevel;
137}
141
143{
144 m_Data.reserve(MAX_CMD_LEN);
145}
146
151{
152 m_Data.reserve(MAX_CMD_LEN);
153 parseBuf(buf);
154}
155
159AUXCommand::AUXCommand(AUXCommands command, AUXTargets source, AUXTargets destination, const AUXBuffer &data)
160{
161 m_Command = command;
162 m_Source = source;
163 m_Destination = destination;
164 m_Data.reserve(MAX_CMD_LEN);
165 m_Data = data;
166 len = 3 + m_Data.size();
167}
168
173{
174 m_Command = command;
175 m_Source = source;
176 m_Destination = destination;
177 m_Data.reserve(MAX_CMD_LEN);
178 len = 3 + m_Data.size();
179}
180
184const char * AUXCommand::commandName(AUXCommands command) const
185{
186 switch (command)
187 {
189 return "PORTCTRL_GET_INPUT_POWER";
191 return "PORTCTRL_SET_POWER_ENABLED";
193 return "PORTCTRL_GET_POWER_ENABLED";
195 return "PORTCTRL_SET_EXT_CURRENT_LIMIT";
197 return "PORTCTRL_GET_EXT_CURRENT_LIMIT";
199 return "PORTCTRL_GET_NUMBER_OF_PORTS";
201 return "PORTCTRL_GET_PORT_INFO";
203 return "PORTCTRL_GET_DH_PORT_INFO";
205 return "PORTCTRL_RESET_FUSE";
207 return "PORTCTRL_SET_PORT_ENABLED";
209 return "PORTCTRL_SET_PORT_VOLTAGE";
211 return "PORTCTRL_DH_ENABLE_AUTO";
213 return "PORTCTRL_DH_ENABLE_MANUAL";
215 return "PORTCTRL_GET_ENVIRONMENT";
217 return "PORTCTRL_ENABLE_SELF_HEATER";
219 return "PORTCTRL_SELF_HEATER_STATUS";
221 return "PORTCTRL_GET_HEATER_LEVEL";
223 return "PORTCTRL_FACTORY_RESET";
225 return "PORTCTRL_GET_VERSION";
227 return "PORTCTRL_SET_LED_BRIGHTNESS";
229 return "PORTCTRL_GET_LED_BRIGHTNESS";
230 case PORTCTRL_NAK:
231 return "PORTCTRL_NAK";
232 default :
233 return nullptr;
234 }
235}
236
241{
242 switch (m_Command)
243 {
245 return 6; // data[0:1] voltage, data[2:3] current, data[4] voltage status, data[5] overcurrent
247 return 1; // <Enabled/Disabled boolean>
249 return 0; // CMD
251 return 4; // <0:1 LIMIT (mA)> <2:3 MAX LIMIT (mA)>
253 return 1; // <Number of Ports>
255 return 7; // <0 type><1 enabled><2 isShorted><3:4 power(mW)><5:6 VoltageLevel (mV)>
257 return 6; // <0 type><nmode><2 power level><3:4 power(mW)><5 aggression level (C)> (min size)
259 return 0; // CMD
261 return 0; // CMD
263 return 0; // CMD
265 return 0; // CMD
267 return 0; // CMD
269 return 9; // <0:3 ambient temp mC><4:7 dew point mC><8 humidity>
271 return 0; // CMD
273 return 1; // <true/false>
275 return 1; // <0 heater level (0 to 255)>
277 return 0; // CMD
279 return 2; // version number (assuming 2 bytes for version)
281 return 0; // CMD
283 return 1; // <0 brightness level>
284 default :
285 return -1;
286 }
287}
288
293{
294 switch (n)
295 {
296 case HC :
297 return "HC";
298 case APP :
299 return "APP";
300 case DEW_POWER_CTRL:
301 return "DEW_POWER_CTRL";
302 default :
303 return nullptr;
304 }
305}
306
311{
312 buf.resize(len + 3);
313
314 buf[0] = 0x3b;
315 buf[1] = len;
316 buf[2] = m_Source;
317 buf[3] = m_Destination;
318 buf[4] = m_Command;
319 for (uint32_t i = 0; i < m_Data.size(); i++)
320 {
321 buf[i + 5] = m_Data[i];
322 }
323 buf.back() = checksum(buf);
324}
325
330{
331 len = buf[1];
332 m_Source = (AUXTargets)buf[2];
333 m_Destination = (AUXTargets)buf[3];
334 m_Command = (AUXCommands)buf[4];
335 m_Data = AUXBuffer(buf.begin() + 5, buf.end() - 1);
336 valid = (checksum(buf) == buf.back());
337 if (valid == false)
338 {
339 DEBUGFDEVICE(DEVICE_NAME, DEBUG_LEVEL, "Checksum error: %02x vs. %02x", checksum(buf), buf.back());
340 };
341}
342
346void AUXCommand::parseBuf(AUXBuffer buf, bool do_checksum)
347{
348 (void)do_checksum;
349
350 len = buf[1];
351 m_Source = (AUXTargets)buf[2];
352 m_Destination = (AUXTargets)buf[3];
353 m_Command = (AUXCommands)buf[4];
354 if (buf.size() > 5)
355 m_Data = AUXBuffer(buf.begin() + 5, buf.end());
356}
357
362{
363 int l = buf[1];
364 int cs = 0;
365 for (int i = 1; i < l + 2; i++)
366 {
367 cs += buf[i];
368 }
369 return (unsigned char)(((~cs) + 1) & 0xFF);
370}
371
376{
377 uint32_t value = 0;
378 switch (m_Data.size())
379 {
380 case 3:
381 value = (m_Data[0] << 16) | (m_Data[1] << 8) | m_Data[2];
382 break;
383
384 case 2:
385 value = (m_Data[0] << 8) | m_Data[1];
386 break;
387
388 case 1:
389 value = m_Data[0];
390 break;
391 }
392
393 return value;
394}
395
399void AUXCommand::setData(uint32_t value, uint8_t bytes)
400{
401 m_Data.resize(bytes);
402 switch (bytes)
403 {
404 case 1:
405 len = 4;
406 m_Data[0] = static_cast<uint8_t>(value >> 0 & 0xff);
407 break;
408 case 2:
409 len = 5;
410 m_Data[1] = static_cast<uint8_t>(value >> 0 & 0xff);
411 m_Data[0] = static_cast<uint8_t>(value >> 8 & 0xff);
412 break;
413
414 case 3:
415 default:
416 len = 6;
417 m_Data[2] = static_cast<uint8_t>(value >> 0 & 0xff);
418 m_Data[1] = static_cast<uint8_t>(value >> 8 & 0xff);
419 m_Data[0] = static_cast<uint8_t>(value >> 16 & 0xff);
420 break;
421 }
422}
void logBytes(unsigned char *buf, int n, const char *deviceName, uint32_t debugLevel)
#define BUFFER_SIZE
std::vector< uint8_t > AUXBuffer
@ PORTCTRL_SET_LED_BRIGHTNESS
@ PORTCTRL_GET_HEATER_LEVEL
@ PORTCTRL_SET_PORT_VOLTAGE
@ PORTCTRL_SET_PORT_ENABLED
@ PORTCTRL_DH_ENABLE_MANUAL
@ PORTCTRL_GET_NUMBER_OF_PORTS
@ PORTCTRL_ENABLE_SELF_HEATER
@ PORTCTRL_GET_DH_PORT_INFO
@ PORTCTRL_SET_EXT_CURRENT_LIMIT
@ PORTCTRL_GET_LED_BRIGHTNESS
@ PORTCTRL_GET_EXT_CURRENT_LIMIT
@ PORTCTRL_SET_POWER_ENABLED
@ PORTCTRL_GET_POWER_ENABLED
@ PORTCTRL_SELF_HEATER_STATUS
AUXCommands command() const
uint8_t checksum(AUXBuffer buf)
Check sum.
uint32_t getData()
Set and Get data.
const char * commandName() const
void parseBuf(AUXBuffer buf)
const char * moduleName(AUXTargets n)
const AUXTargets & source() const
Getters.
const AUXBuffer & data() const
static char DEVICE_NAME[64]
static void setDebugInfo(const char *deviceName, uint8_t debugLevel)
void fillBuf(AUXBuffer &buf)
Buffer Management.
void setData(uint32_t value, uint8_t bytes=3)
Set encoder position in steps.
const AUXTargets & destination() const
#define MAX_CMD_LEN
#define DEBUGFDEVICE(device, priority, msg,...)
Definition indilogger.h:61