25 if (strcmp(response,
"*P99OOO") != 0)
47 if (!formatCommand(
'A', command))
52 if (!sendCommand(command, response))
57 if (strlen(response) < 3)
62 if (response[0] !=
'*' || response[1] !=
'A')
67 *status = response[2] -
'0';
76 if (!formatCommand(
'J', command))
81 if (!sendCommand(command, response))
86 if (strlen(response) < 3)
91 if (response[0] !=
'*' || response[1] !=
'J')
97 return extractIntValue(response, 4, brightness);
115 if (!formatCommand(
'B', command, value))
120 if (!sendCommand(command, response))
125 if (strlen(response) < 3)
130 if (response[0] !=
'*' || response[1] !=
'B')
136 if (!extractIntValue(response, 4, &response_value))
141 return (response_value == value);
149 if (!formatCommand(
'L', command))
154 if (!sendCommand(command, response))
159 return (strlen(response) >= 3 && response[0] ==
'*' && response[1] ==
'L');
167 if (!formatCommand(
'D', command))
172 if (!sendCommand(command, response))
177 return (strlen(response) >= 3 && response[0] ==
'*' && response[1] ==
'D');
185 if (!formatCommand(
'O', command))
195 return (strcmp(response,
"*O99OOO") == 0);
203 if (!formatCommand(
'C', command))
213 return (strcmp(response,
"*C99OOO") == 0);
221 if (!formatCommand(
'S', command))
226 if (!sendCommand(command, response))
231 if (strlen(response) < 7)
236 if (response[0] !=
'*' || response[1] !=
'S')
242 char id_str[3] = {response[2], response[3],
'\0'};
243 int id = atoi(id_str);
244 if (
id != 19 &&
id != 99)
249 *motorStatus = response[4] -
'0';
250 *lightStatus = response[5] -
'0';
251 *coverStatus = response[6] -
'0';
263 snprintf(command,
sizeof(command),
">M-%02d#", value);
267 snprintf(command,
sizeof(command),
">M%03d#", value);
272 return sendCommand(command, response, 30);
280 if (!formatCommand(
'F', command))
285 return sendCommand(command, response);
293 if (!formatCommand(
'E', command))
298 return sendCommand(command, response);
302bool GeminiFlatpanelRev1Adapter::formatCommand(
char commandLetter,
char *commandString,
int value)
304 if (commandString ==
nullptr)
313 snprintf(commandString,
MAXRBUF,
">%c000#", commandLetter);
318 snprintf(commandString,
MAXRBUF,
">%c%03d#", commandLetter, value);
324bool GeminiFlatpanelRev1Adapter::extractIntValue(
const char *response,
int startPos,
int *value)
326 if (response ==
nullptr || value ==
nullptr)
341 snprintf(value_str,
sizeof(value_str),
"%.*s",
static_cast<int>(length), response + startPos);
342 *value = atoi(value_str);
347bool GeminiFlatpanelRev1Adapter::sendCommand(
const char *command,
char *response,
int timeout,
bool log)
349 int nbytes_written = 0, nbytes_read = 0, rc = -1;
351 tcflush(portFD, TCIOFLUSH);
364 if (response ==
nullptr)
379 if (nbytes_read > 0 && response[nbytes_read - 1] ==
'\n')
381 response[nbytes_read - 1] =
'\0';
383 tcflush(portFD, TCIOFLUSH);
385 if (response[0] !=
'*' || response[1] != command[1])
409 if (strcmp(response,
"*HGeminiFlatPanel#") != 0)
426 if (!sendCommand(
">V#", response))
431 if (strlen(response) < 3)
436 if (response[0] !=
'*' || response[1] !=
'V')
442 if (!extractIntValue(response, 2, &firmwareVersion))
447 if (firmwareVersion < 402)
453 *version = firmwareVersion;
463 if (!formatCommand(
'A', command))
468 if (!sendCommand(command, response))
473 if (strlen(response) < 3)
478 if (response[0] !=
'*' || response[1] !=
'A')
483 *status = response[2] -
'0';
492 if (!formatCommand(
'J', command))
497 if (!sendCommand(command, response))
502 if (strlen(response) < 3)
507 if (response[0] !=
'*' || response[1] !=
'J')
513 return extractIntValue(response, 2, brightness);
531 if (!formatCommand(
'B', command, value))
536 if (!sendCommand(command, response))
541 if (strlen(response) < 3)
546 if (response[0] !=
'*' || response[1] !=
'B')
552 if (!extractIntValue(response, 2, &response_value))
557 return (response_value == value);
565 if (!formatCommand(
'L', command))
570 if (!sendCommand(command, response))
575 return (strlen(response) >= 3 && response[0] ==
'*' && response[1] ==
'L');
583 if (!formatCommand(
'D', command))
588 if (!sendCommand(command, response))
593 return (strlen(response) >= 3 && response[0] ==
'*' && response[1] ==
'D');
601 if (!formatCommand(
'O', command))
611 return (strcmp(response,
"*OOpened#") == 0);
619 if (!formatCommand(
'C', command))
629 return (strcmp(response,
"*CClosed#") == 0);
637 if (!formatCommand(
'S', command))
642 if (!sendCommand(command, response))
647 if (strlen(response) < 7)
652 if (response[0] !=
'*' || response[1] !=
'S')
658 char id_str[3] = {response[2], response[3],
'\0'};
659 int id = atoi(id_str);
660 if (
id != 19 &&
id != 99)
665 *motorStatus = response[4] -
'0';
666 *lightStatus = response[5] -
'0';
667 *coverStatus = response[6] -
'0';
679 snprintf(command,
sizeof(command),
">M-%02d#", value);
683 snprintf(command,
sizeof(command),
">M%03d#", value);
688 return sendCommand(command, response, 30);
696 if (!formatCommand(
'F', command))
701 return sendCommand(command, response);
709 if (!formatCommand(
'E', command))
714 return sendCommand(command, response);
727 return sendCommand(command,
nullptr);
739 if (!formatCommand(
'Y', command, mode))
744 return sendCommand(command,
nullptr);
748bool GeminiFlatpanelRev2Adapter::formatCommand(
char commandLetter,
char *commandString,
int value)
750 if (commandString ==
nullptr)
759 snprintf(commandString,
MAXRBUF,
">%c#", commandLetter);
764 snprintf(commandString,
MAXRBUF,
">%c%d#", commandLetter, value);
770bool GeminiFlatpanelRev2Adapter::extractIntValue(
const char *response,
int startPos,
int *value)
772 if (response ==
nullptr || value ==
nullptr)
777 const char *terminator = strchr(response,
'#');
778 if (terminator ==
nullptr)
784 int length = terminator - (response + startPos);
793 snprintf(value_str,
sizeof(value_str),
"%.*s", length, response + startPos);
794 *value = atoi(value_str);
799bool GeminiFlatpanelRev2Adapter::sendCommand(
const char *command,
char *response,
int timeout,
bool log)
801 int nbytes_written = 0, nbytes_read = 0, rc = -1;
803 tcflush(portFD, TCIOFLUSH);
816 if (response ==
nullptr)
831 if (nbytes_read > 0 && response[nbytes_read - 1] ==
'\n')
833 response[nbytes_read - 1] =
'\0';
835 tcflush(portFD, TCIOFLUSH);
837 if (response[0] !=
'*' || response[1] != command[1])
861 if (strcmp(response,
"*HGeminiFlatPanelLite#") != 0)
878 if (!sendCommand(
">V#", response))
883 if (strlen(response) < 3)
888 if (response[0] !=
'*' || response[1] !=
'V')
894 if (!extractIntValue(response, 2, &firmwareVersion))
899 if (firmwareVersion < 205)
905 *version = firmwareVersion;
923 if (!formatCommand(
'J', command))
928 if (!sendCommand(command, response))
933 if (strlen(response) < 3)
938 if (response[0] !=
'*' || response[1] !=
'J')
944 return extractIntValue(response, 2, brightness);
962 if (!formatCommand(
'B', command, value))
967 if (!sendCommand(command, response))
972 if (strlen(response) < 3)
977 if (response[0] !=
'*' || response[1] !=
'B')
983 if (!extractIntValue(response, 2, &response_value))
988 return (response_value == value);
996 if (!formatCommand(
'L', command))
1001 if (!sendCommand(command, response))
1006 return (strlen(response) >= 3 && response[0] ==
'*' && response[1] ==
'L');
1014 if (!formatCommand(
'D', command))
1019 if (!sendCommand(command, response))
1024 return (strlen(response) >= 3 && response[0] ==
'*' && response[1] ==
'D');
1044 if (!formatCommand(
'S', command))
1049 if (!sendCommand(command, response))
1054 if (strlen(response) < 5)
1059 if (response[0] !=
'*' || response[1] !=
'S')
1069 *lightStatus = response[2] -
'0';
1088 return sendCommand(command,
nullptr);
1100 if (!formatCommand(
'Y', command, mode))
1105 return sendCommand(command,
nullptr);
1109bool GeminiFlatpanelLiteAdapter::formatCommand(
char commandLetter,
char *commandString,
int value)
1111 if (commandString ==
nullptr)
1120 snprintf(commandString,
MAXRBUF,
">%c#", commandLetter);
1125 snprintf(commandString,
MAXRBUF,
">%c%d#", commandLetter, value);
1131bool GeminiFlatpanelLiteAdapter::extractIntValue(
const char *response,
int startPos,
int *value)
1133 if (response ==
nullptr || value ==
nullptr)
1138 const char *terminator = strchr(response,
'#');
1139 if (terminator ==
nullptr)
1145 int length = terminator - (response + startPos);
1153 char value_str[
MAXRBUF] = {0};
1154 strncpy(value_str, response + startPos, length);
1155 *value = atoi(value_str);
1160bool GeminiFlatpanelLiteAdapter::sendCommand(
const char *command,
char *response,
int timeout,
bool log)
1162 int nbytes_written = 0, nbytes_read = 0, rc = -1;
1164 tcflush(portFD, TCIOFLUSH);
1177 if (response ==
nullptr)
1192 if (nbytes_read > 0 && response[nbytes_read - 1] ==
'\n')
1194 response[nbytes_read - 1] =
'\0';
1196 tcflush(portFD, TCIOFLUSH);
1198 if (response[0] !=
'*' || response[1] != command[1])
1222 if (strcmp(response,
"*HGeminiFlatPanelPro#") != 0)
1239 if (!sendCommand(
">V#", response))
1244 if (strlen(response) < 3)
1249 if (response[0] !=
'*' || response[1] !=
'V')
1254 int firmwareVersion;
1255 if (!extractIntValue(response, 2, &firmwareVersion))
1260 *version = firmwareVersion;
1276 if (!formatCommand(
'J', command))
1281 if (!sendCommand(command, response))
1286 if (strlen(response) < 4)
1291 if (response[0] !=
'*' || response[1] !=
'J')
1297 return extractIntValue(response, 2, brightness);
1315 if (!formatCommand(
'B', command, value))
1320 if (!sendCommand(command, response))
1325 if (strlen(response) < 3)
1330 if (response[0] !=
'*' || response[1] !=
'B')
1336 if (!extractIntValue(response, 2, &response_value))
1341 return (response_value == value);
1349 if (!formatCommand(
'L', command))
1354 if (!sendCommand(command, response))
1359 return (strlen(response) >= 3 && response[0] ==
'*' && response[1] ==
'L');
1367 if (!formatCommand(
'D', command))
1372 if (!sendCommand(command, response))
1377 return (strlen(response) >= 3 && response[0] ==
'*' && response[1] ==
'D');
1385 if (!formatCommand(
'O', command))
1396 return (response[0] ==
'*' && response[1] ==
'O');
1404 if (!formatCommand(
'C', command))
1415 return (response[0] ==
'*' && response[1] ==
'C');
1423 if (!formatCommand(
'S', command))
1428 if (!sendCommand(command, response))
1433 if (response[0] !=
'*' || response[1] !=
'S')
1438 if (strlen(response) < 7)
1443 *motorStatus = response[2] -
'0';
1444 *lightStatus = response[4] -
'0';
1445 *coverStatus = response[6] -
'0';
1468 if (direction == -1)
1470 snprintf(command,
sizeof(command),
">M-%02d#", value);
1474 snprintf(command,
sizeof(command),
">M%03d#", value);
1479 return sendCommand(command, response, 30);
1487 if (!formatCommand(
'F', command))
1492 return sendCommand(command, response);
1500 if (!formatCommand(
'E', command))
1505 return sendCommand(command, response);
1521bool GeminiFlatpanelProAdapter::formatCommand(
char commandLetter,
char *commandString,
int value)
1523 if (commandString ==
nullptr)
1532 snprintf(commandString,
MAXRBUF,
">%c#", commandLetter);
1537 snprintf(commandString,
MAXRBUF,
">%c%d#", commandLetter, value);
1543bool GeminiFlatpanelProAdapter::extractIntValue(
const char *response,
int startPos,
int *value)
1545 if (response ==
nullptr || value ==
nullptr)
1550 const char *terminator = strchr(response,
'#');
1551 if (terminator ==
nullptr)
1557 int length = terminator - (response + startPos);
1565 char value_str[
MAXRBUF] = {0};
1566 strncpy(value_str, response + startPos, length);
1567 *value = atoi(value_str);
1572bool GeminiFlatpanelProAdapter::sendCommand(
const char *command,
char *response,
int timeout,
bool log)
1574 int nbytes_written = 0, nbytes_read = 0, rc = -1;
1576 tcflush(portFD, TCIOFLUSH);
1589 if (response ==
nullptr)
1604 if (nbytes_read > 0 && response[nbytes_read - 1] ==
'\n')
1606 response[nbytes_read - 1] =
'\0';
1608 tcflush(portFD, TCIOFLUSH);
1610 if (response[0] !=
'*' || response[1] != command[1])
1623 : simulateRev2Features(simulateRev2Features)
1629 simulationValues[SIM_BRIGHTNESS] = 128;
1631 simulationValues[SIM_BEEP_ENABLED] = 0;
1635 if (simulateRev2Features)
1638 simulatedFirmwareVersion = 450;
1643 simulatedFirmwareVersion = 0;
1655 return simulatedRevision;
1660 if (!simulateRev2Features)
1666 *version = simulatedFirmwareVersion;
1672 return simulateRev2Features;
1682 return simulateRev2Features;
1687 *status = simulationValues[SIM_CONFIG_STATUS];
1693 *brightness = simulationValues[SIM_BRIGHTNESS];
1704 simulationValues[SIM_BRIGHTNESS] = value;
1734 *coverStatus = simulationValues[SIM_COVER];
1735 *lightStatus = simulationValues[SIM_LIGHT];
1736 *motorStatus = simulationValues[SIM_MOTOR];
1772 simulationValues[SIM_BEEP_ENABLED] = enable ? 1 : 0;
1788 simulationValues[SIM_BRIGHTNESS_MODE] = mode;
1795 return simulateRev2Features ?
'#' :
'\n';
void log(const std::string &log)
bool getBrightness(int *brightness) override
Get the current brightness level.
bool setBrightnessMode(int mode) override
Set the brightness mode (high/low)
bool openCover() override
Open the dust cover.
bool lightOff() override
Turn the light off.
bool closeCover() override
Close the dust cover.
bool lightOn() override
Turn the light on.
bool ping() override
Ping the device to check if it responds to this adapter's protocol.
char getCommandTerminator() const override
Get the command terminator character for this revision.
bool getConfigStatus(int *status) override
Get the current configuration status.
bool getStatus(int *coverStatus, int *lightStatus, int *motorStatus) override
Get the current device status.
bool setBrightness(int value) override
Set the brightness level.
bool setBeep(bool enable) override
Enable or disable beep functionality.
bool getFirmwareVersion(int *version) override
Get the firmware version from the device.
bool lightOff() override
Turn the light off.
bool setOpenPosition() override
Set the current position as the open position.
bool openCover() override
Open the dust cover.
bool setClosePosition() override
Set the current position as the closed position.
bool getBrightness(int *brightness) override
Get the current brightness level.
bool move(uint16_t value, int direction) override
Move the cover by a specified amount.
bool setBrightness(int value) override
Set the brightness level.
bool getConfigStatus(int *status) override
Get the current configuration status.
bool setBeep(bool enable) override
Enable or disable beep functionality.
bool lightOn() override
Turn the light on.
bool setBrightnessMode(int mode) override
Set the brightness mode (high/low)
char getCommandTerminator() const override
Get the command terminator character for this revision.
bool getStatus(int *coverStatus, int *lightStatus, int *motorStatus) override
Get the current device status.
bool getFirmwareVersion(int *version) override
Get the firmware version from the device.
bool closeCover() override
Close the dust cover.
bool ping() override
Ping the device to check if it responds to this adapter's protocol.
bool setClosePosition() override
Set the current position as the closed position.
bool getConfigStatus(int *status) override
Get the current configuration status.
bool move(uint16_t value, int direction) override
Move the cover by a specified amount.
bool getFirmwareVersion(int *version) override
Get the firmware version from the device.
bool lightOff() override
Turn the light off.
bool openCover() override
Open the dust cover.
bool lightOn() override
Turn the light on.
bool getBrightness(int *brightness) override
Get the current brightness level.
bool setBrightness(int value) override
Set the brightness level.
char getCommandTerminator() const override
Get the command terminator character for this revision.
bool closeCover() override
Close the dust cover.
bool getStatus(int *coverStatus, int *lightStatus, int *motorStatus) override
Get the current device status.
bool ping() override
Ping the device to check if it responds to this adapter's protocol.
bool setOpenPosition() override
Set the current position as the open position.
bool getStatus(int *coverStatus, int *lightStatus, int *motorStatus) override
Get the current device status.
bool lightOff() override
Turn the light off.
bool getConfigStatus(int *status) override
Get the current configuration status.
bool setBrightness(int value) override
Set the brightness level.
char getCommandTerminator() const override
Get the command terminator character for this revision.
bool setBrightnessMode(int mode) override
Set the brightness mode (high/low)
bool setClosePosition() override
Set the current position as the closed position.
bool setOpenPosition() override
Set the current position as the open position.
bool setBeep(bool enable) override
Enable or disable beep functionality.
bool openCover() override
Open the dust cover.
bool getFirmwareVersion(int *version) override
Get the firmware version from the device.
bool move(uint16_t value, int direction) override
Move the cover by a specified amount.
bool getBrightness(int *brightness) override
Get the current brightness level.
bool ping() override
Ping the device to check if it responds to this adapter's protocol.
bool lightOn() override
Turn the light on.
bool closeCover() override
Close the dust cover.
bool getBrightness(int *brightness) override
Get the current brightness level.
GeminiFlatpanelSimulationAdapter(bool simulateRev2Features=true)
bool supportsBrightnessMode() const override
Check if device supports brightness mode selection (high/low)
bool setBeep(bool enable) override
Enable or disable beep functionality.
bool setBrightnessMode(int mode) override
Set the brightness mode (high/low)
bool closeCover() override
Close the dust cover.
bool supportsDustCap() const override
Check if device supports dust cap functionality.
bool openCover() override
Open the dust cover.
int getRevision() const override
Get the firmware revision this adapter supports.
bool getFirmwareVersion(int *version) override
Get the firmware version from the device.
bool lightOn() override
Turn the light on.
bool getStatus(int *coverStatus, int *lightStatus, int *motorStatus) override
Get the current device status.
bool setClosePosition() override
Set the current position as the closed position.
void setupCommunication(int portFD) override
Set up communication parameters for this revision.
char getCommandTerminator() const override
Get the command terminator character for this revision.
bool setBrightness(int value) override
Set the brightness level.
bool supportsBeep() const override
Check if device supports beep functionality.
bool getConfigStatus(int *status) override
Get the current configuration status.
bool lightOff() override
Turn the light off.
bool move(uint16_t value, int direction) override
Move the cover by a specified amount.
bool setOpenPosition() override
Set the current position as the open position.
bool ping() override
Ping the device to check if it responds to this adapter's protocol.
#define SERIAL_TIMEOUT_SEC
@ GEMINI_COVER_STATUS_TIMED_OUT
@ GEMINI_COVER_STATUS_CLOSED
@ GEMINI_COVER_STATUS_OPEN
#define SERIAL_TIMEOUT_SEC_LONG
@ GEMINI_BRIGHTNESS_MODE_HIGH
@ GEMINI_BRIGHTNESS_MODE_LOW
@ GEMINI_MOTOR_STATUS_STOPPED
@ GEMINI_MOTOR_STATUS_RUNNING
@ GEMINI_LIGHT_STATUS_OFF
#define GEMINI_MAX_BRIGHTNESS
#define GEMINI_MIN_BRIGHTNESS
int tty_write_string(int fd, const char *buf, int *nbytes_written)
Writes a null terminated string to fd.
void tty_error_msg(int err_code, char *err_msg, int err_msg_len)
Retrieve the tty error message.
int tty_nread_section(int fd, char *buf, int nsize, char stop_char, int timeout, int *nbytes_read)
read buffer from terminal with a delimiter
Implementations for common driver routines.