19 return "Gemini Flatpanel";
47 DeviceTypeSP[DEVICE_AUTO].
fill(
"AUTO",
"Auto-detect",
ISS_ON);
48 DeviceTypeSP[DEVICE_REV1].
fill(
"REV1",
"Revision 1",
ISS_OFF);
49 DeviceTypeSP[DEVICE_REV2].
fill(
"REV2",
"Revision 2",
ISS_OFF);
50 DeviceTypeSP[DEVICE_LITE].
fill(
"LITE",
"Lite",
ISS_OFF);
51 DeviceTypeSP[DEVICE_PRO].
fill(
"PRO",
"Pro",
ISS_OFF);
80 if (adapter && adapter->supportsBeep())
86 if (adapter && adapter->supportsDustCap())
104 if (adapter && adapter->supportsBeep())
110 if (adapter && adapter->supportsDustCap())
122 if (adapter && adapter->supportsDustCap())
143 DeviceTypeSP.
update(states, names, n);
145 DeviceTypeSP.
apply();
154 if (adapter && adapter->supportsDustCap() &&
DI::processSwitch(dev, name, states, names, n))
197 DeviceTypeSP.
save(fp);
212 StatusTP[STATUS_COVER].
fill(
"COVER",
"Cover",
nullptr);
213 StatusTP[STATUS_LIGHT].
fill(
"LIGHT",
"Light",
nullptr);
214 StatusTP[STATUS_MOTOR].
fill(
"MOTOR",
"Motor",
nullptr);
216 ConfigurationTP.
fill(
224 ConfigurationTP[0].
fill(
"CONFIGURATION",
"Configuration",
nullptr);
248 if (!adapter || !adapter->supportsBeep())
250 LOG_WARN(
"Beep functionality not supported by this device.");
278 ConfigureSP[0].
fill(
"CONFIGURE",
"Configure",
ISS_OFF);
282 ClosedPositionSP.
fill(
291 ClosedPositionSP[MOVEMENT_LIMITS_45].
fill(
"45",
"-45",
ISS_OFF);
292 ClosedPositionSP[MOVEMENT_LIMITS_10].
fill(
"10",
"-10",
ISS_OFF);
293 ClosedPositionSP[MOVEMENT_LIMITS_01].
fill(
"1",
"-1",
ISS_OFF);
306 SetClosedSP[0].
fill(
"SET_CLOSED",
"Set closed",
ISS_OFF);
319 OpenPositionSP[MOVEMENT_LIMITS_45].
fill(
"45",
"45",
ISS_OFF);
320 OpenPositionSP[MOVEMENT_LIMITS_10].
fill(
"10",
"10",
ISS_OFF);
321 OpenPositionSP[MOVEMENT_LIMITS_01].
fill(
"1",
"1",
ISS_OFF);
334 SetOpenSP[0].
fill(
"SET_OPEN",
"Set open",
ISS_OFF);
346 int coverStatus = 0, lightStatus = 0, motorStatus = 0, brightness = 0;
350 error |= !getStatus(&coverStatus, &lightStatus, &motorStatus);
351 error |= !getBrightness(&brightness);
366 if (updateBrightness(brightness))
371 bool statusUpdated = updateCoverStatus(coverStatus) ||
372 updateLightStatus(lightStatus) ||
373 updateMotorStatus(motorStatus);
384 LOG_WARN(
"Motor running with unknown cover status.");
386 updateConfigStatus();
399bool GeminiFlatpanel::applyUnifiedBrightness(
int unifiedValue,
bool forceMode)
404 if ((forceMode || mode != brightnessMode) && !setBrightnessMode(mode))
409 if (!setBrightness(rawValue))
414 brightnessMode = mode;
427 if (!adapter || !adapter->supportsBrightnessMode())
429 return setBrightness((
int)value);
437 return applyUnifiedBrightness(value,
false);
452 if (enable && adapter && adapter->supportsBrightnessMode()
453 && !applyUnifiedBrightness(
static_cast<int>(
LightIntensityNP[0].getValue()),
true))
458 return enable ? lightOn() : lightOff();
503bool GeminiFlatpanel::Handshake()
508 adapter = std::make_unique<GeminiFlatpanelSimulationAdapter>(
true);
509 deviceRevision = adapter->getRevision();
510 commandTerminator = adapter->getCommandTerminator();
513 if (adapter->supportsBrightnessMode())
519 if (adapter && adapter->supportsDustCap())
526 int adapterConfigStatus;
527 if (adapter->getConfigStatus(&adapterConfigStatus))
529 configStatus = adapterConfigStatus;
530 updateConfigStatus();
545 std::function<std::unique_ptr<GeminiFlatpanelAdapter>()> factory;
550 std::vector<AdapterInfo> adapterTypes;
552 if (selectedDeviceType == DEVICE_AUTO)
557 {[]() {
return std::make_unique<GeminiFlatpanelRev1Adapter>(); },
"Rev1", DEVICE_REV1},
558 {[]() {
return std::make_unique<GeminiFlatpanelRev2Adapter>(); },
"Rev2", DEVICE_REV2},
559 {[]() {
return std::make_unique<GeminiFlatpanelLiteAdapter>(); },
"Lite", DEVICE_LITE},
560 {[]() {
return std::make_unique<GeminiFlatpanelProAdapter>(); },
"Pro", DEVICE_PRO}
566 switch (selectedDeviceType)
569 adapterTypes = {{[]() {
return std::make_unique<GeminiFlatpanelRev1Adapter>(); },
"Rev1", DEVICE_REV1}};
572 adapterTypes = {{[]() {
return std::make_unique<GeminiFlatpanelRev2Adapter>(); },
"Rev2", DEVICE_REV2}};
575 adapterTypes = {{[]() {
return std::make_unique<GeminiFlatpanelLiteAdapter>(); },
"Lite", DEVICE_LITE}};
578 adapterTypes = {{[]() {
return std::make_unique<GeminiFlatpanelProAdapter>(); },
"Pro", DEVICE_PRO}};
584 bool connected =
false;
585 for (
const auto &adapterInfo : adapterTypes)
587 auto testAdapter = adapterInfo.factory();
588 testAdapter->setupCommunication(PortFD);
590 if (testAdapter->ping())
592 adapter = std::move(testAdapter);
593 deviceRevision = adapter->getRevision();
594 commandTerminator = adapter->getCommandTerminator();
597 int firmwareVersion = 0;
598 if (adapter->getFirmwareVersion(&firmwareVersion))
601 LOGF_INFO(
"Device revision: %s (Firmware v%d)", adapterInfo.name.c_str(), firmwareVersion);
606 LOGF_INFO(
"Device revision: %s", adapterInfo.name.c_str());
616 LOG_ERROR(
"Handshake failed. Unable to communicate with the device.");
621 if (adapter->supportsBrightnessMode())
627 if (adapter && adapter->supportsDustCap())
634 int adapterConfigStatus;
635 if (adapter->getConfigStatus(&adapterConfigStatus))
637 configStatus = adapterConfigStatus;
638 updateConfigStatus();
648bool GeminiFlatpanel::getBrightness(
int *
const brightness)
650 return adapter ? adapter->getBrightness(brightness) :
false;
653bool GeminiFlatpanel::setBrightness(
int value)
655 return adapter ? adapter->setBrightness(value) :
false;
658bool GeminiFlatpanel::lightOn()
660 return adapter ? adapter->lightOn() :
false;
663bool GeminiFlatpanel::lightOff()
665 return adapter ? adapter->lightOff() :
false;
668bool GeminiFlatpanel::openCover()
670 return adapter ? adapter->openCover() :
false;
673bool GeminiFlatpanel::closeCover()
675 return adapter ? adapter->closeCover() :
false;
678bool GeminiFlatpanel::setBeep(
bool enable)
680 return adapter ? adapter->setBeep(enable) :
false;
683bool GeminiFlatpanel::setBrightnessMode(
int mode)
685 return adapter ? adapter->setBrightnessMode(mode) :
false;
688bool GeminiFlatpanel::getStatus(
int *
const coverStatus,
int *
const lightStatus,
int *
const motorStatus)
690 return adapter ? adapter->getStatus(coverStatus, lightStatus, motorStatus) :
false;
693bool GeminiFlatpanel::move(uint16_t value,
int direction)
695 return adapter ? adapter->move(value, direction) :
false;
698bool GeminiFlatpanel::setClosePosition()
700 return adapter ? adapter->setClosePosition() :
false;
703bool GeminiFlatpanel::setOpenPosition()
705 return adapter ? adapter->setOpenPosition() :
false;
709bool GeminiFlatpanel::updateCoverStatus(
char coverStatus)
711 bool statusUpdated =
false;
713 if (coverStatus != prevCoverStatus)
715 prevCoverStatus = coverStatus;
716 statusUpdated =
true;
721 StatusTP[STATUS_COVER].setText(
"Moving");
727 StatusTP[STATUS_COVER].setText(
"Closed");
738 StatusTP[STATUS_COVER].setText(
"Open");
749 StatusTP[STATUS_COVER].setText(
"Timed Out");
758 return statusUpdated;
761bool GeminiFlatpanel::updateLightStatus(
char lightStatus)
763 bool statusUpdated =
false;
765 if (lightStatus != prevLightStatus)
767 prevLightStatus = lightStatus;
768 statusUpdated =
true;
773 StatusTP[STATUS_LIGHT].setText(
"Off");
782 StatusTP[STATUS_LIGHT].setText(
"On");
793 return statusUpdated;
796bool GeminiFlatpanel::updateMotorStatus(
char motorStatus)
798 bool statusUpdated =
false;
800 if (motorStatus != prevMotorStatus)
802 prevMotorStatus = motorStatus;
803 statusUpdated =
true;
808 StatusTP[STATUS_MOTOR].setText(
"Stopped");
811 StatusTP[STATUS_MOTOR].setText(
"Running");
816 return statusUpdated;
819bool GeminiFlatpanel::updateBrightness(
int brightness)
821 bool statusUpdated =
false;
822 if (brightness != prevBrightness)
824 prevBrightness = brightness;
825 statusUpdated =
true;
830 return statusUpdated;
833void GeminiFlatpanel::updateConfigStatus()
835 const char *configStatusText =
nullptr;
836 switch (configStatus)
839 configStatusText =
"Not ready";
842 configStatusText =
"Ready";
845 configStatusText =
"Open";
848 configStatusText =
"Closed";
851 ConfigurationTP[0].setText(configStatusText);
852 ConfigurationTP.
apply();
862 int adapterConfigStatus;
863 if (adapter && adapter->getConfigStatus(&adapterConfigStatus))
865 configStatus = adapterConfigStatus;
868 LOG_INFO(
"Configuration completed successfully.");
873 LOGF_WARN(
"Invalid configuration status. Please restart configuration in %s tab.",
MOTION_TAB);
879 LOG_WARN(
"Failed to get configuration status.");
893 LOG_WARN(
"Flatpanel not ready. Click the configure button to start configuration.");
903 LOG_WARN(
"Click the configure button to start configuration.");
908 LOG_WARN(
"Please set the closed configuration using the close position controls.");
913 LOG_WARN(
"Please set the open configuration using the open position controls.");
923 currentSwitch.
apply();
929 if (!adapter || !adapter->supportsDustCap())
931 LOG_WARN(
"Dust cap movement not supported by this device.");
947 switch (currentSwitch.findOnSwitchIndex())
949 case MOVEMENT_LIMITS_45:
952 case MOVEMENT_LIMITS_10:
955 case MOVEMENT_LIMITS_01:
961 move(steps, direction);
969 if (!adapter || !adapter->supportsDustCap())
971 LOG_WARN(
"Dust cap position setting not supported by this device.");
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 setDefaultBaudRate(BaudRate newRate)
setDefaultBaudRate Set default baud rate. The default baud rate is 9600 unless otherwise changed by t...
Provides interface to implement remotely controlled dust cover.
virtual IPState UnParkCap() override
unPark dust cap (open cover). Must be implemented by child.
bool saveConfigItems(FILE *fp) override
saveConfigItems Save specific properties in the provide config file handler. Child class usually over...
virtual bool ISSnoopDevice(XMLEle *root) override
Process a snoop event from INDI server. This function is called when a snooped property is updated in...
bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
virtual const char * getDefaultName() override
bool EnableLightBox(bool enable) override
EnableLightBox Turn on/off on a light box. Must be implemented in the child class.
bool validateCalibrationOperation(int direction)
virtual IPState AbortCap() override
Abort motion. Must be implemented by child.
bool SetLightBoxBrightness(uint16_t value) override
setBrightness Set light level. Must be implemented in the child class, if supported.
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
void onSetPosition(int direction)
void ISGetProperties(const char *deviceName) override
define the driver's properties to the client. Usually, only a minimum set of properties are defined t...
void TimerHit() override
Callback function to be called once SetTimer duration elapses.
void onMove(int direction)
bool initProperties() override
Initialize properties initial state and value. The child class must implement this function.
void initLimitsProperties()
void initStatusProperties()
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) override
Process the client newSwitch command.
void startConfiguration()
virtual IPState ParkCap() override
Park dust cap (close cover). Must be implemented by child.
void cleanupSwitch(INDI::PropertySwitch ¤tSwitch, int switchIndex)
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
const char * getDeviceName() const
virtual bool updateProperties()
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
virtual bool saveConfig(bool silent=false, const char *property=nullptr)
Save the current properties in a configuration file.
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...
uint32_t getCurrentPollingPeriod() const
getCurrentPollingPeriod Return the current polling period.
virtual bool initProperties()
Initialize properties initial state and value. The child class must implement this function.
bool isSimulation() const
void syncDriverInfo()
syncDriverInfo sends the current driver information to the client.
void addAuxControls()
Add Debug, Simulation, and Configuration options to the driver.
uint32_t getDriverInterface() const
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
Process the client newNumber command.
int SetTimer(uint32_t ms)
Set a timer to call the function TimerHit after ms milliseconds.
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
Process the client newSwitch command.
INDI::PropertySwitch ParkCapSP
bool updateProperties()
updateProperties Defines or Delete properties based on default device connection status
void initProperties(const char *group, uint32_t capabilities=0)
Initialize dust cap properties. It is recommended to call this function within initProperties() of yo...
bool processSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Process dust cap switch properties.
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 saveConfigItems(FILE *fp)
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.
INDI::PropertySwitch LightSP
void setState(IPState state)
void apply(const char *format,...) const ATTRIBUTE_FORMAT_PRINTF(2
bool load()
load Attempt to load property values from configuration file.
void save(FILE *f) const
save Save property to configuration file.
bool isNameMatch(const char *otherName) const
bool update(const ISState states[], const char *const names[], int n)
int findOnSwitchIndex() const
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, ISRule rule, double timeout, IPState state)
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, double timeout, IPState state)
void onUpdate(const std::function< void()> &callback)
Provides interface to implement controllable light box/switch device.
const char * CONNECTION_TAB
CONNECTION_TAB Where all device connection settings (serial, usb, ethernet) are defined and controlle...
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
const char * MOTION_TAB
MOTION_TAB Where all the motion control properties of the device are located.
@ GEMINI_COVER_STATUS_TIMED_OUT
@ GEMINI_COVER_STATUS_CLOSED
@ GEMINI_COVER_STATUS_OPEN
@ GEMINI_COVER_STATUS_MOVING
@ GEMINI_BRIGHTNESS_MODE_HIGH
@ GEMINI_BRIGHTNESS_MODE_LOW
@ GEMINI_MOTOR_STATUS_STOPPED
@ GEMINI_MOTOR_STATUS_RUNNING
@ GEMINI_LIGHT_STATUS_OFF
#define GEMINI_MAX_BRIGHTNESS
Implementations for common driver routines.
#define LOGF_INFO(fmt,...)
#define LOGF_WARN(fmt,...)
#define LOG_ERROR(txt)
Shorter logging macros. In order to use these macros, the function (or method) "getDeviceName()" must...