35 static 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);
99 SkyQualityUpdateNP[0].
fill(
"VALUE",
"Period (s)",
"%.f", 0, 3600, 60, 60);
105 GPSNP[GPSFix].
fill(
"GPSFix",
"GPS Fix",
"%.f", 0, 3, 1, 0);
106 GPSNP[GPSTime].
fill(
"GPSTime",
"Unix Time",
"%.f", 0, 1e9, 10, 0);
107 GPSNP[UTCOffset].
fill(
"UTCOffset",
"UTC Offset",
"%.2f", -12, 12, 1, 0);
108 GPSNP[Latitude].
fill(
"Latitude",
"Latitude",
"%.2f", -90, 90, 10, 0);
109 GPSNP[Longitude].
fill(
"Longitude",
"Longitude",
"%.2f", -180, 180, 10, 0);
110 GPSNP[SatelliteNumber].
fill(
"SatelliteNumber",
"Sat. #",
"%.f", 0, 30, 10, 0);
111 GPSNP[GPSSpeed].
fill(
"GPSSpeed",
"Speed (kph)",
"%.2f", 0, 30, 10, 0);
112 GPSNP[GPSBearing].
fill(
"GPSBearing",
"Bearing (deg)",
"%.2f", 0, 360, 10, 0);
119 addParameter(
"WEATHER_MPAS",
"MPAS (mag/arcsec^2)", 1, 30, 15);
120 addParameter(
"WEATHER_TEMPERATURE",
"Temperature (C)", -20, 50, 15);
121 addParameter(
"WEATHER_HUMIDITY",
"Humidity (%)", 0, 75, 15);
160 m_SetupComplete =
true;
179 m_SetupComplete =
false;
190 return "Uranus Meteo Sensor";
196 bool UranusMeteo::Handshake()
199 m_SetupComplete =
false;
200 char response[PEGASUS_LEN] = {0};
202 if (sendCommand(
"M#", response))
203 return (!strcmp(response,
"MS_OK"));
213 char response[PEGASUS_LEN] = {0};
215 if (sendCommand(
"GP", response))
217 std::vector<std::string> result = split(response + 3,
":");
226 GPSNP[GPSFix].setValue(std::stod(result[GPSFix]));
227 GPSNP[GPSTime].setValue(std::stod(result[GPSTime]));
228 GPSNP[UTCOffset].setValue(std::stod(result[UTCOffset]));
229 GPSNP[Latitude].setValue(std::stod(result[Latitude]));
230 GPSNP[Longitude].setValue(std::stod(result[Longitude]));
231 GPSNP[SatelliteNumber].setValue(std::stod(result[SatelliteNumber]));
232 GPSNP[GPSSpeed].setValue(std::stod(result[GPSSpeed]));
233 GPSNP[GPSBearing].setValue(std::stod(result[GPSBearing]));
238 if (GPSNP[GPSFix].getValue() < 3)
251 time_t raw_time = GPSNP[GPSTime].getValue();
255 struct tm *local = localtime(&raw_time);
257 auto utcOffset = local->tm_gmtoff / 3600.0;
259 time_t utcTime = raw_time - utcOffset * 3600.0;
261 struct tm *utc = gmtime(&utcTime);
263 strftime(ts,
sizeof(ts),
"%Y-%m-%dT%H:%M:%S", utc);
266 snprintf(ts,
sizeof(ts),
"%.2f", utcOffset);
270 char command[PEGASUS_LEN] = {0};
271 snprintf(command, PEGASUS_LEN,
"C3:%d",
static_cast<int>(utcOffset));
272 sendCommand(command, response);
278 LOGF_WARN(
"Failed to process sensor response: %s (%d bytes)", response, strlen(response));
291 setParameterValue(
"WEATHER_TEMPERATURE", SensorNP[AmbientTemperature].getValue());
322 SkyQualityUpdateNP.
update(values, names, n);
323 auto value = SkyQualityUpdateNP[0].getValue();
326 m_SkyQualityUpdateTimer.
start(value * 1000);
331 LOG_INFO(
"Sky Quality Update is disabled.");
334 SkyQualityUpdateNP.
apply();
369 SkyQualityUpdateNP.
save(fp);
376 bool UranusMeteo::readSensors()
378 char response[PEGASUS_LEN] = {0};
380 if (sendCommand(
"MA", response))
382 std::vector<std::string> result =
split(response + 6,
":");
384 if (result == m_Sensors)
391 SensorNP[AmbientTemperature].setValue(std::stod(result[AmbientTemperature]));
392 SensorNP[RelativeHumidity].setValue(std::stod(result[RelativeHumidity]));
393 SensorNP[DewPoint].setValue(std::stod(result[DewPoint]));
394 SensorNP[AbsolutePressure].setValue(std::stod(result[AbsolutePressure]));
395 SensorNP[BarometricAltitude].setValue(std::stod(result[BarometricAltitude]));
396 SensorNP[SkyTemperature].setValue(std::stod(result[SkyTemperature]));
397 SensorNP[InfraredTemperature].setValue(std::stod(result[InfraredTemperature]));
398 SensorNP[BatteryUsage].setValue(std::stod(result[BatteryUsage]));
399 SensorNP[BatteryVoltage].setValue(std::stod(result[BatteryVoltage]));
407 LOGF_WARN(
"Failed to process sensor response: %s (%d bytes)", response, strlen(response));
418 bool UranusMeteo::readSkyQuality()
420 char response[PEGASUS_LEN] = {0};
422 if (sendCommand(
"SQ", response))
424 std::vector<std::string> result =
split(response + 3,
":");
426 if (result == m_SkyQuality)
429 m_SkyQuality = result;
433 SkyQualityNP[MPAS].setValue(std::stod(result[MPAS]));
434 SkyQualityNP[NELM].setValue(std::stod(result[NELM]));
435 SkyQualityNP[FullSpectrum].setValue(std::stod(result[FullSpectrum]));
436 SkyQualityNP[VisualSpectrum].setValue(std::stod(result[VisualSpectrum]));
437 SkyQualityNP[InfraredSpectrum].setValue(std::stod(result[InfraredSpectrum]));
440 SkyQualityNP.
apply();
445 LOGF_WARN(
"Failed to process sky quality response: %s (%d bytes)", response, strlen(response));
456 bool UranusMeteo::readClouds()
458 char response[PEGASUS_LEN] = {0};
460 if (sendCommand(
"CI", response))
462 std::vector<std::string> result =
split(response + 3,
":");
464 if (result == m_Clouds)
471 CloudsNP[TemperatureDifference].setValue(std::stod(result[TemperatureDifference]));
472 CloudsNP[CloudIndex].setValue(std::stod(result[CloudIndex]));
473 CloudsNP[CloudSkyTemperature].setValue(std::stod(result[CloudSkyTemperature]));
474 CloudsNP[CloudAmbientTemperature].setValue(std::stod(result[CloudAmbientTemperature]));
475 CloudsNP[InfraredEmissivity].setValue(std::stod(result[InfraredEmissivity]));
483 LOGF_WARN(
"Failed to process cloud response: %s (%d bytes)", response, strlen(response));
494 void UranusMeteo::measureSkyQuality()
496 char response[PEGASUS_LEN] = {0};
498 if (sendCommand(
"SQ:1", response))
501 if (SkyQualityUpdateNP[0].getValue() > 0)
502 m_SkyQualityUpdateTimer.
start(SkyQualityUpdateNP[0].getValue() * 1000);
509 bool UranusMeteo::readMoon()
517 bool UranusMeteo::readTwilight()
525 bool UranusMeteo::readConfig()
533 bool UranusMeteo::sendCommand(
const char *
cmd,
char * res)
535 int nbytes_read = 0, nbytes_written = 0, tty_rc = 0;
536 char command[PEGASUS_LEN] = {0};
539 for (
int i = 0; i < 2; i++)
541 tcflush(PortFD, TCIOFLUSH);
542 snprintf(command, PEGASUS_LEN,
"%s\r\n",
cmd);
548 tcflush(PortFD, TCIOFLUSH);
552 if ( (tty_rc =
tty_nread_section(PortFD, res, PEGASUS_LEN, PEGASUS_STOP_CHAR, PEGASUS_TIMEOUT, &nbytes_read)) !=
TTY_OK
556 tcflush(PortFD, TCIOFLUSH);
557 res[nbytes_read - 2] =
'\0';
576 std::vector<std::string> UranusMeteo::split(
const std::string &input,
const std::string ®ex)
579 std::regex re(regex);
580 std::sregex_token_iterator
581 first{input.begin(), input.end(), re, -1},
583 return {first, last};
void registerHandshake(std::function< bool()> callback)
registerHandshake Register a handshake function to be called once the intial connection to the device...
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...
const char * getDeviceName() const
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 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.
void setDriverInterface(uint16_t value)
setInterface Set driver interface. By default the driver interface is set to GENERAL_DEVICE....
int SetTimer(uint32_t ms)
Set a timer to call the function TimerHit after ms milliseconds.
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
INDI::PropertyNumber LocationNP
INDI::PropertyText TimeTP
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
Initilize 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 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 functionality.
bool processSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Process weather switch properties.
void setParameterValue(std::string name, double value)
setParameterValue Update weather parameter value
bool setCriticalParameter(std::string param)
setCriticalParameter Set parameter that is considered critical to the operation of the observatory....
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 addParameter(std::string name, std::string label, double numMinOk, double numMaxOk, double percWarning)
addParameter Add a physical weather measurable parameter to the weather driver. The weather value has...
void initProperties(const char *statusGroup, const char *paramsGroup)
Initilize focuser properties. It is recommended to call this function within initProperties() of your...
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
TimerHit Keep calling updateGPS() until it is successfull, if it fails upon first connection.
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
Initilize 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,...)
std::vector< std::string > split(const std::string &input, const std::string ®ex)