35static std::unique_ptr<UranusMeteo> ppba(
new UranusMeteo());
44 m_SkyQualityUpdateTimer.
callOnTimeout(std::bind(&UranusMeteo::measureSkyQuality,
this));
67 SensorNP[AmbientTemperature].
fill(
"AmbientTemperature",
"AmbientTemperature",
"%.2f", -100, 100, 10, 0);
68 SensorNP[RelativeHumidity].
fill(
"RelativeHumidity",
"RelativeHumidity",
"%.2f%", 0, 100, 10, 0);
69 SensorNP[DewPoint].
fill(
"DewPoint",
"DewPoint (C)",
"%.2f", 0, 100, 10, 0);
70 SensorNP[AbsolutePressure].
fill(
"AbsolutePressure",
"AbsolutePressure (hPA)",
"%.2f", 0, 100, 10, 0);
71 SensorNP[RelativePressure].
fill(
"RelativePressure",
"RelativePressure (hPA)",
"%.2f", 0, 100, 10, 0);
72 SensorNP[BarometricAltitude].
fill(
"BarometricAltitude",
"BarometricAltitude (m)",
"%.2f", 0, 100, 10, 0);
73 SensorNP[SkyTemperature].
fill(
"SkyTemperature",
"SkyTemperature (C)",
"%.2f", 0, 100, 10, 0);
74 SensorNP[InfraredTemperature].
fill(
"InfraredTemperature",
"InfraredTemperature (C)",
"%.2f", 0, 100, 10, 0);
75 SensorNP[BatteryUsage].
fill(
"BatteryUsage",
"BatteryUsage",
"%.2f%", 0, 100, 10, 0);
76 SensorNP[BatteryVoltage].
fill(
"BatteryVoltage",
"BatteryVoltage",
"%.2f", 0, 100, 10, 0);
82 CloudsNP[TemperatureDifference].
fill(
"TemperatureDifference",
"Temperature Difference (C)",
"%.2f", -1000, 1000, 10, 0);
83 CloudsNP[CloudIndex].
fill(
"CloudIndex",
"Cloud Coverage (%)",
"%.2f", 0, 100, 10, 0);
84 CloudsNP[CloudSkyTemperature].
fill(
"CloudSkyTemperature",
"Sky Temperature (C)",
"%.2f", -1000, 1000, 10, 0);
85 CloudsNP[CloudAmbientTemperature].
fill(
"CloudAmbientTemperature",
"Ambient Temperature (C)",
"%.2f", -1000, 1000, 10, 0);
86 CloudsNP[InfraredEmissivity].
fill(
"InfraredEmissivity",
"Infrared Emissivity",
"%.2f", 0, 1, 0.1, 0);
92 SkyQualityNP[MPAS].
fill(
"MPAS",
"MPAS (mag/arcsec^2)",
"%.2f", 0, 30, 10, 0);
93 SkyQualityNP[NELM].
fill(
"NELM",
"Naked Eye Llimit (mag)",
"%.2f", 0, 100, 10, 0);
94 SkyQualityNP[FullSpectrum].
fill(
"FullSpectrum",
"Full Spectrum",
"%.2f", -1000, 1000, 10, 0);
95 SkyQualityNP[VisualSpectrum].
fill(
"VisualSpectrum",
"Visual Spectrum",
"%.2f", -1000, 1000, 10, 0);
96 SkyQualityNP[InfraredSpectrum].
fill(
"InfraredSpectrum",
"Infrared Spectrum",
"%.2f", 0, 1, 0.1, 0);
97 SkyQualityNP[Lux].
fill(
"Lux",
"Lux",
"%.2f", 0, 1e6, 10, 0);
100 SkyQualityUpdateNP[0].
fill(
"VALUE",
"Period (s)",
"%.f", 0, 3600, 60, 60);
106 GPSNP[GPSFix].
fill(
"GPSFix",
"GPS Fix",
"%.f", 0, 3, 1, 0);
107 GPSNP[GPSTime].
fill(
"GPSTime",
"Unix Time",
"%.f", 0, 1e9, 10, 0);
108 GPSNP[UTCOffset].
fill(
"UTCOffset",
"UTC Offset",
"%.2f", -12, 12, 1, 0);
109 GPSNP[Latitude].
fill(
"Latitude",
"Latitude",
"%.2f", -90, 90, 10, 0);
110 GPSNP[Longitude].
fill(
"Longitude",
"Longitude",
"%.2f", -180, 180, 10, 0);
111 GPSNP[SatelliteNumber].
fill(
"SatelliteNumber",
"Sat. #",
"%.f", 0, 30, 10, 0);
112 GPSNP[Altitude].
fill(
"Altitude",
"Altitude (m)",
"%.2f", -1000, 10000, 10, 0);
113 GPSNP[GPSSpeed].
fill(
"GPSSpeed",
"Speed (kph)",
"%.2f", 0, 30, 10, 0);
114 GPSNP[GPSBearing].
fill(
"GPSBearing",
"Bearing (deg)",
"%.2f", 0, 360, 10, 0);
121 addParameter(
"WEATHER_MPAS",
"MPAS (mag/arcsec^2)", 1, 30, 15);
122 addParameter(
"WEATHER_TEMPERATURE",
"Temperature (C)", -20, 50, 15);
123 addParameter(
"WEATHER_HUMIDITY",
"Humidity (%)", 0, 75, 15);
162 m_SetupComplete =
true;
181 m_SetupComplete =
false;
192 return "Uranus Meteo Sensor";
198bool UranusMeteo::Handshake()
201 m_SetupComplete =
false;
202 char response[PEGASUS_LEN] = {0};
204 if (sendCommand(
"M#", response))
205 return (!strcmp(response,
"MS_OK"));
215 char response[PEGASUS_LEN] = {0};
217 if (sendCommand(
"GP", response))
219 std::vector<std::string> result = split(response + 3,
":");
228 GPSNP[GPSFix].setValue(std::stod(result[GPSFix]));
229 GPSNP[GPSTime].setValue(std::stod(result[GPSTime]));
230 GPSNP[UTCOffset].setValue(std::stod(result[UTCOffset]));
231 GPSNP[Latitude].setValue(std::stod(result[Latitude]));
232 GPSNP[Longitude].setValue(std::stod(result[Longitude]));
233 GPSNP[SatelliteNumber].setValue(std::stod(result[SatelliteNumber]));
234 GPSNP[Altitude].setValue(std::stod(result[Altitude]));
235 GPSNP[GPSSpeed].setValue(std::stod(result[GPSSpeed]));
236 GPSNP[GPSBearing].setValue(std::stod(result[GPSBearing]));
241 if (GPSNP[GPSFix].getValue() < 3)
257 time_t raw_time =
static_cast<time_t
>(GPSNP[GPSTime].getValue());
266 struct tm *utc = gmtime(&raw_time);
268 strftime(ts,
sizeof(ts),
"%Y-%m-%dT%H:%M:%S", utc);
271 auto utcOffset = GPSNP[UTCOffset].getValue();
272 snprintf(ts,
sizeof(ts),
"%.2f", utcOffset);
276 char command[PEGASUS_LEN] = {0};
277 snprintf(command, PEGASUS_LEN,
"C3:%d",
static_cast<int>(utcOffset));
278 sendCommand(command, response);
284 LOGF_WARN(
"Failed to process sensor response: %s (%d bytes)", response, strlen(response));
297 setParameterValue(
"WEATHER_TEMPERATURE", SensorNP[AmbientTemperature].getValue());
328 SkyQualityUpdateNP.
update(values, names, n);
329 auto value = SkyQualityUpdateNP[0].getValue();
332 m_SkyQualityUpdateTimer.
start(value * 1000);
337 LOG_INFO(
"Sky Quality Update is disabled.");
340 SkyQualityUpdateNP.
apply();
375 SkyQualityUpdateNP.
save(fp);
382bool UranusMeteo::readSensors()
384 char response[PEGASUS_LEN] = {0};
386 if (sendCommand(
"MA", response))
388 std::vector<std::string> result = split(response + 6,
":");
390 if (result == m_Sensors)
397 SensorNP[AmbientTemperature].setValue(std::stod(result[AmbientTemperature]));
398 SensorNP[RelativeHumidity].setValue(std::stod(result[RelativeHumidity]));
399 SensorNP[DewPoint].setValue(std::stod(result[DewPoint]));
400 SensorNP[AbsolutePressure].setValue(std::stod(result[AbsolutePressure]));
401 SensorNP[BarometricAltitude].setValue(std::stod(result[BarometricAltitude]));
402 SensorNP[SkyTemperature].setValue(std::stod(result[SkyTemperature]));
403 SensorNP[InfraredTemperature].setValue(std::stod(result[InfraredTemperature]));
404 SensorNP[BatteryUsage].setValue(std::stod(result[BatteryUsage]));
405 SensorNP[BatteryVoltage].setValue(std::stod(result[BatteryVoltage]));
413 LOGF_WARN(
"Failed to process sensor response: %s (%d bytes)", response, strlen(response));
424bool UranusMeteo::readSkyQuality()
426 char response[PEGASUS_LEN] = {0};
428 if (sendCommand(
"SQ", response))
430 std::vector<std::string> result = split(response + 3,
":");
432 if (result == m_SkyQuality)
435 m_SkyQuality = result;
439 SkyQualityNP[MPAS].setValue(std::stod(result[MPAS]));
440 SkyQualityNP[NELM].setValue(std::stod(result[NELM]));
441 SkyQualityNP[FullSpectrum].setValue(std::stod(result[FullSpectrum]));
442 SkyQualityNP[VisualSpectrum].setValue(std::stod(result[VisualSpectrum]));
443 SkyQualityNP[InfraredSpectrum].setValue(std::stod(result[InfraredSpectrum]));
444 SkyQualityNP[Lux].setValue(std::stod(result[Lux]));
447 SkyQualityNP.
apply();
452 LOGF_WARN(
"Failed to process sky quality response: %s (%d bytes)", response, strlen(response));
463bool UranusMeteo::readClouds()
465 char response[PEGASUS_LEN] = {0};
467 if (sendCommand(
"CI", response))
469 std::vector<std::string> result = split(response + 3,
":");
471 if (result == m_Clouds)
478 CloudsNP[TemperatureDifference].setValue(std::stod(result[TemperatureDifference]));
479 CloudsNP[CloudIndex].setValue(std::stod(result[CloudIndex]));
480 CloudsNP[CloudSkyTemperature].setValue(std::stod(result[CloudSkyTemperature]));
481 CloudsNP[CloudAmbientTemperature].setValue(std::stod(result[CloudAmbientTemperature]));
482 CloudsNP[InfraredEmissivity].setValue(std::stod(result[InfraredEmissivity]));
490 LOGF_WARN(
"Failed to process cloud response: %s (%d bytes)", response, strlen(response));
501void UranusMeteo::measureSkyQuality()
503 char response[PEGASUS_LEN] = {0};
505 if (sendCommand(
"SQ:1", response))
508 if (SkyQualityUpdateNP[0].getValue() > 0)
509 m_SkyQualityUpdateTimer.
start(SkyQualityUpdateNP[0].getValue() * 1000);
516bool UranusMeteo::readMoon()
524bool UranusMeteo::readTwilight()
532bool UranusMeteo::readConfig()
540bool UranusMeteo::sendCommand(
const char *
cmd,
char * res)
542 int nbytes_read = 0, nbytes_written = 0, tty_rc = 0;
543 char command[PEGASUS_LEN] = {0};
546 for (
int i = 0; i < 2; i++)
548 tcflush(PortFD, TCIOFLUSH);
549 snprintf(command, PEGASUS_LEN,
"%s\r\n",
cmd);
555 tcflush(PortFD, TCIOFLUSH);
559 if ( (tty_rc =
tty_nread_section(PortFD, res, PEGASUS_LEN, PEGASUS_STOP_CHAR, PEGASUS_TIMEOUT, &nbytes_read)) !=
TTY_OK
563 tcflush(PortFD, TCIOFLUSH);
564 res[nbytes_read - 2] =
'\0';
583std::vector<std::string> UranusMeteo::split(
const std::string &input,
const std::string ®ex)
586 std::regex re(regex);
587 std::sregex_token_iterator
588 first{input.begin(), input.end(), re, -1},
590 return {first, last};
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...
void registerConnection(Connection::Interface *newConnection)
registerConnection Add new connection plugin to the existing connection pool. The connection type sha...
void setDefaultPollingPeriod(uint32_t msec)
setDefaultPollingPeriod Change the default polling period to call TimerHit() function in the driver.
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)
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.
INDI::PropertyNumber LocationNP
INDI::PropertyText TimeTP
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
virtual bool initProperties() override
Initialize properties initial state and value. The child class must implement this function.
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Save refresh period
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.
void setLabel(const char *label)
bool isNameMatch(const char *otherName) const
bool update(const double values[], 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)
void callOnTimeout(const std::function< void()> &callback)
void start()
Starts or restarts the timer with the timeout specified in interval.
void setInterval(int msec)
Set the timeout interval in milliseconds.
Provides interface to implement weather reporting and safety monitoring functionality.
void addParameter(std::string name, std::string label, double numMinOk, double numMaxOk, double percWarning, bool flipWarning=false)
Add a physical weather measurable parameter to the weather driver.
bool processSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Process weather switch properties.
bool setCriticalParameter(std::string name)
setCriticalParameter Set parameter that is considered critical to the operation of the observatory....
void setParameterValue(std::string name, double value)
setParameterValue Update weather parameter value
bool processNumber(const char *dev, const char *name, double values[], char *names[], int n)
Process weather number properties.
virtual bool saveConfigItems(FILE *fp)
saveConfigItems Save parameters ranges in the config file.
void initProperties(const char *statusGroup, const char *paramsGroup)
Initialize focuser properties. It is recommended to call this function within initProperties() of you...
INDI::PropertySwitch RefreshSP
bool updateProperties()
updateProperties Define or Delete Rotator properties based on the connection status of the base devic...
INDI::PropertyNumber UpdatePeriodNP
virtual void TimerHit() override
Callback function to be called once SetTimer duration elapses.
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Save refresh period
virtual IPState updateWeather() override
updateWeather Update weather conditions from device or service. The function should not change the st...
const char * getDefaultName() override
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
virtual bool initProperties() override
Initialize properties initial state and value. The child class must implement this function.
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
virtual IPState updateGPS() override
updateGPS Retrieve Location & Time from GPS. Update LocationNP & TimeTP properties (value and state) ...
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
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.
void IUSaveText(IText *tp, const char *newtext)
Function to reliably save new text in a IText.
#define LOGF_WARN(fmt,...)
#define LOGF_DEBUG(fmt,...)
#define LOGF_ERROR(fmt,...)