30#ifdef _USE_SYSTEM_JSONLIB
31#include <nlohmann/json.hpp>
53 MotorStatsNP[0].
fill(
"Voltage",
"Voltage",
"%0.2f V", 0.0, 24.0, 0.01, 0.00);
54 MotorStatsNP[1].
fill(
"Current",
"Current",
"%0.2f A", 0.0, 24.0, 0.01, 0.00);
57 FirmwareTP[0].
fill(
"Version",
"Version",
nullptr);
58 FirmwareTP[1].
fill(
"Serial",
"Serial",
nullptr);
61 IPAddressTP[0].
fill(
"IP Address",
"IP Address",
nullptr);
64 DiscoverSwitchSP[0].
fill(
"DISCOVER",
"Discover",
ISS_OFF);
67 SafetySensorLP[0].
fill(
"SAFETY_SENSOR_1",
"Safety Sensor 1",
IPS_IDLE);
68 SafetySensorLP[1].
fill(
"SAFETY_SENSOR_2",
"Safety Sensor 2",
IPS_IDLE);
69 SafetySensorLP[2].
fill(
"SAFETY_SENSOR_3",
"Safety Sensor 3",
IPS_IDLE);
70 SafetySensorLP[3].
fill(
"SAFETY_SENSOR_4",
"Safety Sensor 4",
IPS_IDLE);
73 LimitSwitchLP[0].
fill(
"LIMIT_SWITCH_1",
"Fully Open Switch",
IPS_IDLE);
74 LimitSwitchLP[1].
fill(
"LIMIT_SWITCH_2",
"Fully Closed Switch",
IPS_IDLE);
101 if (strlen(IPAddressTP[0].
getText()) == 0)
120 return (
const char *)
"DragonLAIR";
127 DiscoverSwitchSP.
update(states, names, n);
136 DiscoverSwitchSP.
apply();
147 IPAddressTP.
update(texts, names, n);
191 IPAddressTP.
save(fp);
202 auto state = Dome::getDomeState();
208 LOG_WARN(
"Roof is already fully opened.");
213 LOG_WARN(
"Roof is already fully closed.");
218 LOG_INFO(
"Cannot close dome when mount is locking. See: Telescope parking policy, in options tab");
258 LOG_INFO(
"Roll off is unparking...");
275void DragonLAIR::updateStatus()
277 if (strlen(IPAddressTP[0].
getText()) == 0)
304 std::string version = j[
"version"];
305 std::string serial = j[
"serialNumber"];
306 uint32_t voltageMV = j[
"voltage"];
307 uint32_t currentMA = j[
"current"];
309 MotorStatsNP[0].setValue(voltageMV / 1000.0);
310 MotorStatsNP[1].setValue(currentMA / 1000.0);
312 MotorStatsNP.
apply();
314 FirmwareTP[0].setText(version.c_str());
315 FirmwareTP[1].setText(serial.c_str());
319 std::string safetySensor1 = j[
"roof"][
"safetySensor1"];
320 std::string safetySensor2 = j[
"roof"][
"safetySensor2"];
321 std::string safetySensor3 = j[
"roof"][
"safetySensor3"];
322 std::string safetySensor4 = j[
"roof"][
"safetySensor4"];
328 SafetySensorLP.
apply();
330 bool isRoofFullyClosed = j[
"roof"][
"isRoofFullyClosed"];
331 bool isRoofFullyOpen = j[
"roof"][
"isRoofFullyOpen"];
335 LimitSwitchLP.
apply();
337 bool isRoofClosing = j[
"roof"][
"isRoofClosing"];
338 bool isRoofOpening = j[
"roof"][
"isRoofOpening"];
340 if (isRoofFullyClosed)
347 else if (isRoofFullyOpen)
354 else if (isRoofClosing)
361 else if (isRoofOpening)
368 else if (Dome::getDomeState() !=
DOME_IDLE)
378 catch(
const std::exception &e)
380 LOGF_ERROR(
"Error on updateStatus: %s", e.what());
384void DragonLAIR::openRoof()
386 if (strlen(IPAddressTP[0].
getText()) == 0)
396 auto result = cli.Post(
"/indi/roof/open");
412 catch(
const std::exception &e)
414 LOGF_ERROR(
"Error on openRoof: %s", e.what());
418void DragonLAIR::closeRoof()
420 if (strlen(IPAddressTP[0].
getText()) == 0)
430 auto result = cli.Post(
"/indi/roof/close");
446 catch(
const std::exception &e)
448 LOGF_ERROR(
"Error on closeRoof: %s", e.what());
452void DragonLAIR::stopRoof()
454 if (strlen(IPAddressTP[0].
getText()) == 0)
464 auto result = cli.Post(
"/indi/roof/abort");
480 catch(
const std::exception &e)
482 LOGF_ERROR(
"Error on stopRoof: %s", e.what());
486#define DDA_DISCOVERY_PORT 0xdda
487#define DDA_DISCOVERY_TIMEOUT 2
488#define DDA_DISCOVERY_RECEIVE_BUFFER_SIZE 256
490void DragonLAIR::discoverDevices()
494 s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
497 LOG_ERROR(
"Error creating socket for discovery.");
502 setsockopt(s, SOL_SOCKET, SO_BROADCAST, &broadcast,
sizeof(broadcast));
507 setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv,
sizeof(tv));
509 struct sockaddr_in Recv_addr;
511 socklen_t len =
sizeof(
struct sockaddr_in);
513 Recv_addr.sin_family = AF_INET;
515 Recv_addr.sin_addr.s_addr = INADDR_BROADCAST;
517 const char* sendMSG =
"darkdragons";
519 sendto(s, sendMSG, strlen(sendMSG), 0, (sockaddr *)&Recv_addr,
sizeof(Recv_addr));
530 nlohmann::json doc = nlohmann::json::parse(recvbuff,
nullptr,
false,
true);
534 char deviceIP[INET_ADDRSTRLEN];
535 inet_ntop(AF_INET, &(Recv_addr.sin_addr), deviceIP, INET_ADDRSTRLEN);
537 std::string deviceType = doc[
"deviceType"];
538 std::string serialNumber = doc[
"serialNumber"];
540 LOGF_INFO(
"Found %s %s at %s", deviceType.c_str(), serialNumber.c_str(), deviceIP);
546 DiscoverSwitchSP.
reset();
549 DiscoverSwitchSP.
apply();
virtual bool Abort() override
Abort all dome motion.
virtual IPState Move(DomeDirection dir, DomeMotionCommand operation) override
Move the Dome in a particular direction.
virtual IPState Park() override
Goto Park Position. The park position is an absolute azimuth value.
virtual bool initProperties() override
Initialize properties initial state and value. The child class must implement this function.
bool Disconnect() override
Disconnect from device.
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Saves the Device Port and Dome Presets in the configuration file
const char * getDefaultName() override
bool Connect() override
Connect to the device. INDI::DefaultDevice implementation connects to appropriate connection interfac...
bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) override
Process the client newSwitch command.
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
virtual IPState UnPark() override
UnPark dome. The action of the Unpark command is dome specific, but it may include opening the shutte...
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 ISSnoopDevice(XMLEle *root) override
Process a snoop event from INDI server. This function is called when a snooped property is updated in...
void TimerHit() override
Callback function to be called once SetTimer duration elapses.
INDI::PropertyText getText(const char *name) const
bool isDeviceNameMatch(const char *otherName) const
Check that the device name matches the argument.
virtual bool loadConfig(bool silent=false, const char *property=nullptr)
Load the last saved configuration file.
virtual bool deleteProperty(const char *propertyName)
Delete a property and unregister it. It will also be deleted from all clients.
void defineProperty(INumberVectorProperty *property)
uint32_t getCurrentPollingPeriod() const
getCurrentPollingPeriod Return the current polling period.
void addAuxControls()
Add Debug, Simulation, and Configuration options to the driver.
int SetTimer(uint32_t ms)
Set a timer to call the function TimerHit after ms milliseconds.
void SetParked(bool isparked)
SetParked Change the mount parking status. The data park file (stored in ~/.indi/ParkData....
void SetDomeCapability(uint32_t cap)
SetDomeCapability set the dome capabilities. All capabilities must be initialized.
void setDomeConnection(const uint8_t &value)
setDomeConnection Set Dome connection mode. Child class should call this in the constructor before Do...
virtual 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 initProperties() override
Initialize properties initial state and value. The child class must implement this function.
bool isLocked()
isLocked, is the dome currently locked?
virtual bool updateProperties() override
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) override
Process the client newSwitch command.
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 saveConfigItems(FILE *fp) override
saveConfigItems Saves the Device Port and Dome Presets in the configuration file
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) override
Process the client newSwitch command.
void setDomeState(const DomeState &value)
bool InitPark()
InitPark Loads parking data (stored in ~/.indi/ParkData.xml) that contains parking status and parking...
void SetParkDataType(DomeParkData type)
setParkDataType Sets the type of parking data stored in the park data file and presented to the user.
virtual IPState Move(DomeDirection dir, DomeMotionCommand operation)
Move the Dome in a particular direction.
void setState(IPState state)
void apply(const char *format,...) const ATTRIBUTE_FORMAT_PRINTF(2
void save(FILE *f) const
save Save property to configuration file.
bool isNameMatch(const char *otherName) const
void fill(const char *device, const char *name, const char *label, const char *group, IPState state)
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, double timeout, IPState state)
bool update(const ISState states[], const char *const names[], int n)
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, ISRule rule, double timeout, IPState state)
bool update(const char *const texts[], const char *const names[], int n)
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, double timeout, IPState state)
const Response & value() const
a class to store JSON values
bool contains(const typename object_t::key_type &key) const
check the existence of an element in a JSON object
constexpr bool is_discarded() const noexcept
return whether value is discarded
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
const char * INFO_TAB
INFO_TAB Where all the properties for general information are located.
std::unique_ptr< DragonLAIR > dragonlair(new DragonLAIR())
#define DDA_DISCOVERY_TIMEOUT
#define DDA_DISCOVERY_RECEIVE_BUFFER_SIZE
#define DDA_DISCOVERY_PORT
#define LOGF_INFO(fmt,...)
#define LOG_ERROR(txt)
Shorter logging macros. In order to use these macros, the function (or method) "getDeviceName()" must...
#define LOGF_ERROR(fmt,...)