27#include <libnova/julian_day.h>
49 m_ClientID = getpid();
50 LOG_DEBUG(
"Initializing from alpacaTelescope device...");
55 return "Alpaca Telescope";
67 DeviceInfoTP[DESCRIPTION].
fill(
"DESCRIPTION",
"Description",
"");
68 DeviceInfoTP[DRIVER_INFO].
fill(
"DRIVER_INFO",
"Driver Info",
"");
69 DeviceInfoTP[DRIVER_VERSION].
fill(
"DRIVER_VERSION",
"Driver Version",
"");
70 DeviceInfoTP[INTERFACE_VERSION].
fill(
"INTERFACE_VERSION",
"Interface Version",
"");
121 LOGF_INFO(
"Connecting to alpaca server at %s:%d", host.c_str(), port);
123 httpClient = std::make_unique<httplib::Client>(host.c_str(), port);
124 httpClient->set_connection_timeout(10);
125 httpClient->set_read_timeout(30);
128 if (!sendAlpacaGET(
"/connected", response))
130 LOG_ERROR(
"Failed to connect to alpaca");
135 LOGF_INFO(
"alpaca reachable, connected=%s",
136 response.
value(
"Value",
false) ?
"true" :
"false");
139 request[
"Connected"] =
true;
140 if (!sendAlpacaPUT(
"/connected", request, response))
142 LOG_ERROR(
"Failed to set connected state");
155 LOG_INFO(
"Successfully connected to alpaca");
164 request[
"Connected"] =
false;
165 sendAlpacaPUT(
"/connected", request, response);
168 LOG_INFO(
"Disconnected from alpaca");
176 if (sendAlpacaGET(
"/description", response) && response.
contains(
"Value"))
177 DeviceInfoTP[DESCRIPTION].setText(response[
"Value"].get<std::string>().c_str());
179 if (sendAlpacaGET(
"/driverinfo", response) && response.
contains(
"Value"))
180 DeviceInfoTP[DRIVER_INFO].setText(response[
"Value"].get<std::string>().c_str());
182 if (sendAlpacaGET(
"/driverversion", response) && response.
contains(
"Value"))
183 DeviceInfoTP[DRIVER_VERSION].setText(response[
"Value"].get<std::string>().c_str());
185 if (sendAlpacaGET(
"/interfaceversion", response) && response.
contains(
"Value"))
186 DeviceInfoTP[INTERFACE_VERSION].setText(std::to_string(response[
"Value"].get<int>()).c_str());
188 DeviceInfoTP.
apply();
192 if (sendAlpacaGET(
"/alignmentmode", response) && response.
contains(
"Value"))
194 int alignmentMode = response[
"Value"].
get<
int>();
195 if (alignmentMode == 1)
197 LOG_INFO(
"Telescope alignment mode: Alt-Az (no meridian flips)");
199 else if (alignmentMode == 0 || alignmentMode == 2)
201 LOG_INFO(
"Telescope alignment mode: Equatorial (Fork mount - no meridian flips)");
205 bool canPark =
false;
206 if (sendAlpacaGET(
"/canpark", response) && response.
contains(
"Value"))
207 canPark = response[
"Value"].
get<
bool>();
220 LOG_INFO(
"Park position initialized to zenith");
224 if (sendAlpacaGET(
"/atpark", response) && response.
contains(
"Value"))
226 isParked = response[
"Value"].
get<
bool>();
232 double latitude = 0.0, longitude = 0.0;
233 bool locationValid =
false;
235 if (sendAlpacaGET(
"/sitelatitude", response) && response.
contains(
"Value"))
237 latitude = response[
"Value"].
get<
double>();
238 locationValid =
true;
239 LOGF_INFO(
"Site latitude from device: %.6f°", latitude);
243 LOG_WARN(
"Failed to get site latitude from device");
246 if (sendAlpacaGET(
"/sitelongitude", response) && response.
contains(
"Value"))
248 longitude = response[
"Value"].
get<
double>();
249 LOGF_INFO(
"Site longitude from device: %.6f°", longitude);
253 LOG_WARN(
"Failed to get site longitude from device");
254 locationValid =
false;
258 double elevation = 0.0;
259 if (sendAlpacaGET(
"/siteelevation", response) && response.
contains(
"Value"))
261 elevation = response[
"Value"].
get<
double>();
262 LOGF_INFO(
"Site elevation from device: %.1fm", elevation);
266 LOG_WARN(
"Failed to get site elevation from device");
281 double latRad = latitude *
M_PI / 180.0;
282 m_sinLat = sin(latRad);
283 m_cosLat = cos(latRad);
285 LOGF_INFO(
"Site location set: Lat=%.6f° Long=%.6f°", latitude, longitude);
289 if (sendAlpacaGET(
"/utcdate", response) && response.
contains(
"Value"))
291 std::string utcDate = response[
"Value"].
get<std::string>();
296 LOGF_INFO(
"Device UTC date/time: %s", utcDate.c_str());
300 LOG_WARN(
"Failed to get UTC date/time from device, using system time");
305 if (sendAlpacaGET(
"/cansettracking", response) && response.
contains(
"Value"))
307 if (response[
"Value"].get<bool>())
310 LOG_INFO(
"Telescope supports tracking control - TELESCOPE_TRACK_STATE enabled");
314 LOG_INFO(
"Telescope does not support tracking control");
319 LOG_WARN(
"Failed to query tracking capability from device");
324 if (sendAlpacaGET(
"/canslewasync", response) && response.
contains(
"Value"))
325 m_CanSlewAsync = response[
"Value"].
get<
bool>();
327 m_CanSlewAsync =
false;
328 LOGF_INFO(
"Telescope supports async slew: %s", m_CanSlewAsync ?
"Yes" :
"No");
332 m_TrackModeAlpacaRates.clear();
334 if (sendAlpacaGET(
"/trackingrates", response) && response.
contains(
"Value") && response[
"Value"].
is_array())
336 static const struct {
int rate;
const char *name;
const char *label; } alpacaRates[] =
338 {0,
"TRACK_SIDEREAL",
"Sidereal"},
339 {1,
"TRACK_LUNAR",
"Lunar"},
340 {2,
"TRACK_SOLAR",
"Solar"},
341 {3,
"TRACK_KING",
"King"},
344 for (
const auto &entry : alpacaRates)
346 for (
const auto &value : response[
"Value"])
348 if (value.get<
int>() == entry.rate)
351 m_TrackModeAlpacaRates.push_back(entry.rate);
358 if (!m_TrackModeAlpacaRates.empty())
361 LOGF_INFO(
"Telescope supports %zu tracking rate(s)", m_TrackModeAlpacaRates.size());
364 if (sendAlpacaGET(
"/trackingrate", response) && response.
contains(
"Value"))
366 int currentRate = response[
"Value"].
get<
int>();
367 for (
size_t i = 0; i < m_TrackModeAlpacaRates.size(); i++)
369 if (m_TrackModeAlpacaRates[i] == currentRate)
380 LOG_WARN(
"Failed to query supported tracking rates from device");
384 m_CanSetRaRate = sendAlpacaGET(
"/cansetrightascensionrate", response) && response.
contains(
"Value")
385 && response[
"Value"].
get<
bool>();
386 m_CanSetDecRate = sendAlpacaGET(
"/cansetdeclinationrate", response) && response.
contains(
"Value")
387 && response[
"Value"].
get<
bool>();
389 if (m_CanSetRaRate && m_CanSetDecRate)
392 LOG_INFO(
"Telescope supports custom tracking rates - TELESCOPE_TRACK_RATE enabled");
396 LOG_INFO(
"Telescope does not support custom tracking rates");
402 LOG_INFO(
"alpaca connected successfully");
411 double newRA = m_currentRA, newDec = m_currentDEC;
414 bool raUpdated =
false, decUpdated =
false;
415 if (sendAlpacaGET(
"/rightascension", response) && response.
contains(
"Value"))
417 newRA = response[
"Value"].
get<
double>();
422 LOG_WARN(
"Failed to get RA from Alpaca API");
425 if (sendAlpacaGET(
"/declination", response) && response.
contains(
"Value"))
427 newDec = response[
"Value"].
get<
double>();
432 LOG_WARN(
"Failed to get Dec from Alpaca API");
436 if (raUpdated && decUpdated)
439 m_currentDEC = newDec;
443 NewRaDec(m_currentRA, m_currentDEC);
447 LOG_WARN(
"NewRaDec NOT called - coordinate update failed");
451 if (sendAlpacaGET(
"/slewing", response) && response.
contains(
"Value"))
452 isSlewing = response[
"Value"].
get<
bool>();
455 if (sendAlpacaGET(
"/tracking", response) && response.
contains(
"Value"))
456 isTracking = response[
"Value"].get<bool>();
461 int currentRate = response[
"Value"].
get<
int>();
463 for (
size_t i = 0; i < m_TrackModeAlpacaRates.size(); i++)
465 if (m_TrackModeAlpacaRates[i] == currentRate &&
static_cast<int>(i) != currentIndex)
477 if (sendAlpacaGET(
"/atpark", response) && response.
contains(
"Value"))
479 bool parked = response[
"Value"].
get<
bool>();
480 if (parked != isParked)
494 LOG_INFO(
"Parking complete - telescope at park position");
515 LOG_ERROR(
"Cannot GoTo while parked. Please unpark the telescope first.");
525 raRequest[
"TargetRightAscension"] =
ra;
526 if (!sendAlpacaPUT(
"/targetrightascension", raRequest, response))
534 decRequest[
"TargetDeclination"] =
dec;
535 if (!sendAlpacaPUT(
"/targetdeclination", decRequest, response))
545 const char *slewEndpoint = m_CanSlewAsync ?
"/slewtotargetasync" :
"/slewtotarget";
546 if (!sendAlpacaPUT(slewEndpoint, emptyRequest, response))
548 LOG_ERROR(
"Failed to send GoTo command");
553 LOGF_INFO(
"GoTo command sent (%s) - slewing to target", m_CanSlewAsync ?
"async" :
"sync");
560 request[
"RightAscension"] =
ra;
561 request[
"Declination"] =
dec;
563 if (!sendAlpacaPUT(
"/synctocoordinates", request, response))
580 LOG_WARN(
"Cannot abort parking operation - park must complete");
584 if (!sendAlpacaPUT(
"/abortslew", request, response))
602 LOG_INFO(
"Aborting slew before park");
604 sendAlpacaPUT(
"/abortslew", abortReq, abortResp);
607 LOG_INFO(
"Sending park command to Alpaca device");
610 if (!sendAlpacaPUT(
"/park", request, response))
612 LOG_ERROR(
"Failed to send park command to Alpaca device");
620 LOG_INFO(
"Park command sent - telescope parked");
629 LOG_INFO(
"Sending unpark command to Alpaca device");
632 if (!sendAlpacaPUT(
"/unpark", request, response))
634 LOG_ERROR(
"Failed to send unpark command to Alpaca device");
643 LOG_INFO(
"Unpark command sent - telescope unparked");
655 double ra = 0,
dec = 0;
657 if (sendAlpacaGET(
"/rightascension", response) && response.
contains(
"Value"))
659 ra = response[
"Value"].
get<
double>();
663 LOG_ERROR(
"Failed to get current RA for SetCurrentPark");
667 if (sendAlpacaGET(
"/declination", response) && response.
contains(
"Value"))
669 dec = response[
"Value"].
get<
double>();
673 LOG_ERROR(
"Failed to get current Dec for SetCurrentPark");
681 LOGF_INFO(
"Park position set to current coordinates: RA=%.6f hours, Dec=%.6f degrees",
ra,
dec);
689 request[
"Tracking"] = enabled;
691 if (!sendAlpacaPUT(
"/tracking", request, response))
693 LOGF_ERROR(
"Failed to %s tracking", enabled ?
"enable" :
"disable");
697 isTracking = enabled;
698 LOGF_INFO(
"Tracking %s", enabled ?
"enabled" :
"disabled");
704 if (mode >= m_TrackModeAlpacaRates.size())
711 request[
"TrackingRate"] = m_TrackModeAlpacaRates[mode];
713 if (!sendAlpacaPUT(
"/trackingrate", request, response))
725 if (!m_CanSetRaRate || !m_CanSetDecRate)
727 LOG_WARN(
"Custom tracking rates are not supported by this telescope");
736 request[
"RightAscensionRate"] = raRate / 15.0;
737 if (!sendAlpacaPUT(
"/rightascensionrate", request, response))
739 LOG_ERROR(
"Failed to set RA tracking rate");
744 request[
"DeclinationRate"] = deRate;
745 if (!sendAlpacaPUT(
"/declinationrate", request, response))
747 LOG_ERROR(
"Failed to set DEC tracking rate");
751 LOGF_INFO(
"Custom tracking rate set: RA=%.6f arcsec/s, DEC=%.6f arcsec/s", raRate, deRate);
768 request[
"Rate"] = rate;
773 request[
"Rate"] = 0.0;
777 if (!sendAlpacaPUT(
"/moveaxis", request, response))
784 if (response.
contains(
"ErrorNumber"))
786 int errNum = response[
"ErrorNumber"].
get<
int>();
789 LOGF_WARN(
"MoveAxis NS returned error %d: %s", errNum,
790 response.
value(
"ErrorMessage",
"Unknown error").c_str());
810 request[
"Rate"] = rate;
815 request[
"Rate"] = 0.0;
819 if (!sendAlpacaPUT(
"/moveaxis", request, response))
826 if (response.
contains(
"ErrorNumber"))
828 int errNum = response[
"ErrorNumber"].
get<
int>();
831 LOGF_WARN(
"MoveAxis WE returned error %d: %s", errNum,
832 response.
value(
"ErrorMessage",
"Unknown error").c_str());
851 request[
"SiteLatitude"] = latitude;
852 if (!sendAlpacaPUT(
"/sitelatitude", request, response))
854 LOG_ERROR(
"Failed to set site latitude on device");
860 request[
"SiteLongitude"] = longitude;
861 if (!sendAlpacaPUT(
"/sitelongitude", request, response))
863 LOG_ERROR(
"Failed to set site longitude on device");
869 request[
"SiteElevation"] = elevation;
870 if (!sendAlpacaPUT(
"/siteelevation", request, response))
871 LOG_WARN(
"Failed to set site elevation on device");
874 double latRad = latitude *
M_PI / 180.0;
875 m_sinLat = sin(latRad);
876 m_cosLat = cos(latRad);
878 LOGF_INFO(
"Site location updated: Lat=%.6f° Long=%.6f°", latitude, longitude);
890 snprintf(isoDate,
sizeof(isoDate),
"%04d-%02d-%02dT%02d:%02d:%06.3fZ",
891 utc->years, utc->months, utc->days, utc->hours, utc->minutes, utc->seconds);
894 request[
"UTCDate"] = isoDate;
895 if (!sendAlpacaPUT(
"/utcdate", request, response))
897 LOG_ERROR(
"Failed to set UTC date/time on device");
905std::string alpacaTelescopeDriver::getAlpacaURL(
const std::string& endpoint)
907 return "/api/v1/telescope/" + std::to_string(m_DeviceNumber) + endpoint;
910bool alpacaTelescopeDriver::sendAlpacaGET(
const std::string& endpoint,
nlohmann::json& response)
914 LOG_ERROR(
"HTTP client not initialized");
918 std::string url = getAlpacaURL(endpoint);
919 url +=
"?ClientID=" + std::to_string(m_ClientID) +
920 "&ClientTransactionID=" + std::to_string(getTransactionId());
922 auto result = httpClient->Get(url.c_str());
926 LOGF_ERROR(
"GET %s failed: %s", endpoint.c_str(),
931 if (result->status != 200)
933 LOGF_ERROR(
"GET %s HTTP %d", endpoint.c_str(), result->status);
939 response = nlohmann::json::parse(result->body);
941 if (response.
contains(
"ErrorNumber") && response[
"ErrorNumber"].get<
int>() != 0)
943 LOGF_ERROR(
"Alpaca error %s: %d - %s", endpoint.c_str(),
944 response[
"ErrorNumber"].get<
int>(),
945 response.
value(
"ErrorMessage",
"").c_str());
953 LOGF_ERROR(
"JSON parse error %s: %s", endpoint.c_str(), e.
what());
958bool alpacaTelescopeDriver::sendAlpacaPUT(
const std::string& endpoint,
const nlohmann::json& request,
963 LOG_ERROR(
"HTTP client not initialized");
967 std::string url = getAlpacaURL(endpoint);
972 for (
auto& [key, value] : request.items())
974 if (value.is_string())
975 params.emplace(key, value.get<std::string>());
976 else if (value.is_boolean())
977 params.emplace(key, value.get<
bool>() ?
"true" :
"false");
978 else if (value.is_number_integer())
979 params.emplace(key, std::to_string(value.get<
int>()));
980 else if (value.is_number())
981 params.emplace(key, std::to_string(value.get<
double>()));
984 params.emplace(
"ClientID", std::to_string(m_ClientID));
985 params.emplace(
"ClientTransactionID", std::to_string(getTransactionId()));
987 auto result = httpClient->Put(url.c_str(), params);
993 if (endpoint ==
"/slewtotarget")
995 LOGF_DEBUG(
"PUT %s: connection closed (expected for some devices)", endpoint.c_str());
999 LOGF_ERROR(
"PUT %s failed: %s", endpoint.c_str(),
1005 if (result->status != 200)
1007 LOGF_ERROR(
"PUT %s HTTP %d", endpoint.c_str(), result->status);
1013 response = nlohmann::json::parse(result->body);
1015 if (response.
contains(
"ErrorNumber") && response[
"ErrorNumber"].get<
int>() != 0)
1017 int errorNum = response[
"ErrorNumber"].
get<
int>();
1018 std::string errorMsg = response.
value(
"ErrorMessage",
"");
1019 LOGF_ERROR(
"Alpaca error %s: %d - %s", endpoint.c_str(), errorNum, errorMsg.c_str());
1027 LOGF_ERROR(
"JSON parse error %s: %s", endpoint.c_str(), e.
what());
1034 alpaca->ISGetProperties(dev);
1039 alpaca->ISNewSwitch(dev, name, states, names, n);
1042void ISNewText(
const char *dev,
const char *name,
char *texts[],
char *names[],
int n)
1044 alpaca->ISNewText(dev, name, texts, names, n);
1047void ISNewNumber(
const char *dev,
const char *name,
double values[],
char *names[],
int n)
1049 alpaca->ISNewNumber(dev, name, values, names, n);
1052void ISNewBLOB(
const char *dev,
const char *name,
int sizes[],
int blobsizes[],
char *blobs[],
char *formats[],
1053 char *names[],
int n)
1055 alpaca->ISNewBLOB(dev, name, sizes, blobsizes, blobs, formats, names, n);
1060 alpaca->ISSnoopDevice(root);
void setDefaultHost(const char *addressHost)
void setDefaultPort(uint32_t addressPort)
virtual const char * host() const
virtual uint32_t port() const
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)
uint32_t getCurrentPollingPeriod() const
getCurrentPollingPeriod Return the current polling period.
int SetTimer(uint32_t ms)
Set a timer to call the function TimerHit after ms milliseconds.
void addDebugControl()
Add Debug control to the driver.
void setState(IPState state)
void apply(const char *format,...) const ATTRIBUTE_FORMAT_PRINTF(2
int findOnSwitchIndex() const
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, double timeout, IPState state)
TelescopeStatus TrackState
void SetAxis1Park(double value)
SetRAPark Set current RA/AZ parking position. The data park file (stored in ~/.indi/ParkData....
void SetAxis1ParkDefault(double steps)
SetRAPark Set default RA/AZ parking position.
void SetTelescopeCapability(uint32_t cap, uint8_t slewRateCount)
SetTelescopeCapability sets the Telescope capabilities. All capabilities must be initialized.
virtual bool initProperties() override
Called to initialize basic properties required all the time.
void setTelescopeConnection(const uint8_t &value)
setTelescopeConnection Set telescope connection mode. Child class should call this in the constructor...
virtual int AddTrackMode(const char *name, const char *label, bool isDefault=false)
AddTrackMode.
virtual bool updateProperties() override
Called when connected state changes, to add/remove properties.
virtual void SetParked(bool isparked)
SetParked Change the mount parking status. The data park file (stored in ~/.indi/ParkData....
Connection::TCP * tcpConnection
virtual bool updateLocation(double latitude, double longitude, double elevation)
Update telescope location settings.
@ TELESCOPE_HAS_TRACK_RATE
@ TELESCOPE_HAS_TRACK_MODE
@ TELESCOPE_CAN_CONTROL_TRACK
uint32_t GetTelescopeCapability() const
GetTelescopeCapability returns the capability of the Telescope.
void NewRaDec(double ra, double dec)
The child class calls this function when it has updates.
bool InitPark()
InitPark Loads parking data (stored in ~/.indi/ParkData.xml) that contains parking status and parking...
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Save specific properties in the provide config file handler. Child class usually over...
void SetAxis2Park(double steps)
SetDEPark Set current DEC/ALT parking position. The data park file (stored in ~/.indi/ParkData....
void SetParkDataType(TelescopeParkData type)
setParkDataType Sets the type of parking data stored in the park data file and presented to the user.
void SetAxis2ParkDefault(double steps)
SetDEParkDefault Set default DEC/ALT parking position.
virtual bool Goto(double ra, double dec) override
Move the scope to the supplied RA and DEC coordinates.
virtual bool Disconnect() override
Disconnect from device.
virtual bool SetTrackEnabled(bool enabled) override
SetTrackEnabled Engages or disengages mount tracking. If there are no tracking modes available,...
virtual bool ReadScopeStatus() override
Read telescope status.
virtual bool updateLocation(double latitude, double longitude, double elevation) override
Update telescope location settings.
virtual bool Abort() override
Abort any telescope motion including tracking if possible.
virtual const char * getDefaultName() override
virtual bool Connect() override
Connect to the device. INDI::DefaultDevice implementation connects to appropriate connection interfac...
virtual bool UnPark() override
Unpark the telescope if already parked.
virtual bool MoveWE(INDI_DIR_WE dir, TelescopeMotionCommand command) override
Move the telescope in the direction dir.
virtual bool initProperties() override
Called to initialize basic properties required all the time.
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Save specific properties in the provide config file handler. Child class usually over...
virtual bool Sync(double ra, double dec) override
Set the telescope current RA and DEC coordinates to the supplied RA and DEC coordinates.
virtual bool Handshake() override
perform handshake with device to check communication
virtual bool SetCurrentPark() override
SetCurrentPark Set current coordinates/encoders value as the desired parking position.
virtual bool SetTrackMode(uint8_t mode) override
SetTrackMode Set active tracking mode. Do not change track state.
virtual bool updateTime(ln_date *utc, double utc_offset) override
Update telescope time, date, and UTC offset.
virtual bool updateProperties() override
Called when connected state changes, to add/remove properties.
virtual bool MoveNS(INDI_DIR_NS dir, TelescopeMotionCommand command) override
Start or Stop the telescope motion in the direction dir.
virtual bool Park() override
Park the telescope to its home position.
virtual bool SetTrackRate(double raRate, double deRate) override
SetTrackRate Set custom tracking rates.
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
void clear() noexcept
clears the contents
constexpr bool is_array() const noexcept
return whether value is an array
std::decay< ValueType >::type value(const KeyType &key, ValueType &&default_value) const
access specified object element with default value
auto get() const noexcept(noexcept(std::declval< const basic_json_t & >().template get_impl< ValueType >(detail::priority_tag< 4 > {}))) -> decltype(std::declval< const basic_json_t & >().template get_impl< ValueType >(detail::priority_tag< 4 > {}))
get a (pointer) value (explicit)
general exception of the basic_json class
const char * what() const noexcept override
returns the explanatory string
const char * OPTIONS_TAB
OPTIONS_TAB Where all the driver's options are located. Those may include auxiliary controls,...
INDI::PropertySwitch TrackModeSP
INDI::PropertyText TimeTP
void sendTimeFromSystem()
INDI::PropertyNumber LocationNP
INDI::PropertyNumber ParkPositionNP
std::unique_ptr< alpacaTelescopeDriver > alpaca(new alpacaTelescopeDriver())
void ISNewBLOB(const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n)
Update data of an existing blob vector property.
void ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Update the value of an existing switch vector property.
void ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
Update the value of an existing text vector property.
void ISGetProperties(const char *dev)
Get Device Properties.
void ISSnoopDevice(XMLEle *root)
Function defined by Drivers that is called when another Driver it is snooping (by having previously c...
void ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
Implementations for common driver routines.
#define LOGF_INFO(fmt,...)
#define LOGF_WARN(fmt,...)
#define LOGF_DEBUG(fmt,...)
#define LOG_ERROR(txt)
Shorter logging macros. In order to use these macros, the function (or method) "getDeviceName()" must...
#define LOGF_ERROR(fmt,...)
std::string to_string(Error error)
std::multimap< std::string, std::string > Params
static Logger & getInstance()
Method to get a reference to the object (i.e., Singleton) It is a static method.
int addDebugLevel(const char *debugLevelName, const char *LoggingLevelName)
Adds a new debugging level to the driver.