40static std::unique_ptr<MBox> mbox(
new MBox());
56 addParameter(
"WEATHER_TEMPERATURE",
"Temperature (C)", -10, 30, 15);
57 addParameter(
"WEATHER_BAROMETER",
"Barometer (mbar)", 20, 32.5, 15);
58 addParameter(
"WEATHER_HUMIDITY",
"Humidity %", 0, 100, 15);
59 addParameter(
"WEATHER_DEWPOINT",
"Dew Point (C)", 0, 100, 15);
69 CalibrationNP[CAL_TEMPERATURE].
fill(
"CAL_TEMPERATURE",
"Temperature",
"%.f", -50, 50, 1, 0);
70 CalibrationNP[CAL_PRESSURE].
fill(
"CAL_PRESSURE",
"Pressure",
"%.f", -100, 100, 10, 0);
71 CalibrationNP[CAL_HUMIDITY].
fill(
"CAL_HUMIDITY",
"Humidity",
"%.f", -50, 50, 1, 0);
76 FirmwareTP[0].
fill(
"VERSION",
"Version",
"--");
111 AckResponse rc = ACK_ERROR;
113 for (
int i = 0; i < 3; i++)
120 if (rc == ACK_OK_STARTUP)
122 getCalibration(
false);
125 else if (rc == ACK_OK_INIT)
141 if (getCalibration(
true))
144 CalibrationNP.
apply();
152 strncpy(response,
"$PXDR,P,96276.0,P,0,C,31.8,C,1,H,40.8,P,2,C,16.8,C,3,1.1*31\r\n",
MBOX_BUF);
153 nbytes_read = strlen(response);
162 LOGF_ERROR(
"%s error: %s.", __FUNCTION__, errstr);
166 tcflush(
PortFD, TCIOFLUSH);
170 response[nbytes_read - 2] =
'\0';
174 if (verifyCRC(response) ==
false)
181 char *end = strstr(response,
"*");
185 std::vector<std::string> result = split(response,
",");
187 setParameterValue(
"WEATHER_BAROMETER", std::stod(result[SENSOR_PRESSURE]) / 100.0);
191 if (strcmp(result[FIRMWARE].c_str(), FirmwareTP[0].
getText()))
193 FirmwareTP[0].setText(result[FIRMWARE].c_str());
201MBox::AckResponse MBox::ack()
208 strncpy(response,
"MBox by Astromi.ch\r\n", 64);
209 nbytes_read = strlen(response);
219 LOGF_ERROR(
"%s error: %s.", __FUNCTION__, errstr);
224 if (response[0] ==
'\n')
229 LOGF_ERROR(
"%s error: %s.", __FUNCTION__, errstr);
236 response[nbytes_read - 2] =
'\0';
240 if (strstr(response,
"MBox"))
241 return ACK_OK_STARTUP;
243 else if (strstr(response,
"PXDR"))
255 double prevPressure = CalibrationNP[CAL_PRESSURE].getValue();
256 double prevTemperature = CalibrationNP[CAL_TEMPERATURE].getValue();
257 double prevHumidaty = CalibrationNP[CAL_HUMIDITY].getValue();
258 CalibrationNP.
update(values, names, n);
259 double targetPressure = CalibrationNP[CAL_PRESSURE].getValue();
260 double targetTemperature = CalibrationNP[CAL_TEMPERATURE].getValue();
261 double targetHumidity = CalibrationNP[CAL_HUMIDITY].getValue();
264 if (targetPressure != prevPressure)
266 rc = setCalibration(CAL_PRESSURE);
269 if (targetTemperature != prevTemperature)
271 rc = setCalibration(CAL_TEMPERATURE);
274 if (targetHumidity != prevHumidaty)
276 rc = setCalibration(CAL_HUMIDITY);
280 CalibrationNP.
apply();
294 if (resetCalibration())
298 LOG_INFO(
"Calibration values are reset.");
300 CalibrationNP[CAL_PRESSURE].setValue(0);
301 CalibrationNP[CAL_TEMPERATURE].setValue(0);
302 CalibrationNP[CAL_HUMIDITY].setValue(0);
304 CalibrationNP.
apply();
320bool MBox::getCalibration(
bool sendCommand)
322 int nbytes_written = 0, nbytes_read = 0;
324 const char *command =
":calget*";
332 strncpy(response,
"$PCAL,P,20,T,50,H,-10*79\r\n", 64);
333 nbytes_read = strlen(response);
342 tcflush(
PortFD, TCIOFLUSH);
347 LOGF_ERROR(
"%s write error: %s.", __FUNCTION__, errstr);
355 LOGF_ERROR(
"%s read error: %s.", __FUNCTION__, errstr);
360 if (strstr(response,
"$PCAL") ==
nullptr)
365 LOGF_ERROR(
"%s read error: %s.", __FUNCTION__, errstr);
372 response[nbytes_read - 2] =
'\0';
376 if (verifyCRC(response) ==
false)
383 char *end = strstr(response,
"*");
387 std::vector<std::string> result = split(response,
",");
388 CalibrationNP[CAL_PRESSURE].setValue(std::stod(result[SENSOR_PRESSURE]) / 10.0);
389 CalibrationNP[CAL_TEMPERATURE].setValue(std::stod(result[SENSOR_PRESSURE + 2]) / 10.0);
390 CalibrationNP[CAL_HUMIDITY].setValue(std::stod(result[SENSOR_PRESSURE + 4]) / 10.0);
394bool MBox::setCalibration(CalibrationType
type)
396 int nbytes_written = 0, rc = -1;
398 char command[16] = {0};
400 if (
type == CAL_PRESSURE)
403 snprintf(command, 16,
":calp,%d*",
static_cast<int32_t
>(CalibrationNP[CAL_PRESSURE].getValue() * 10.0));
409 tcflush(
PortFD, TCIOFLUSH);
414 LOGF_ERROR(
"%s error: %s.", __FUNCTION__, errstr);
420 else if (
type == CAL_TEMPERATURE)
423 snprintf(command, 16,
":calt,%d*",
static_cast<int32_t
>(CalibrationNP[CAL_TEMPERATURE].getValue() * 10.0));
429 tcflush(
PortFD, TCIOFLUSH);
434 LOGF_ERROR(
"%s error: %s.", __FUNCTION__, errstr);
442 snprintf(command, 16,
":calh,%d*",
static_cast<int32_t
>(CalibrationNP[CAL_HUMIDITY].getValue() * 10.0));
448 tcflush(
PortFD, TCIOFLUSH);
453 LOGF_ERROR(
"%s error: %s.", __FUNCTION__, errstr);
460 return getCalibration(
false);
463bool MBox::resetCalibration()
465 const char *command =
":calreset*";
470 int nbytes_written = 0, rc = -1;
471 tcflush(
PortFD, TCIOFLUSH);
477 LOGF_ERROR(
"%s error: %s.", __FUNCTION__, errstr);
485bool MBox::verifyCRC(
const char *response)
488 uint8_t calculated_checksum = 0, response_checksum = 0;
490 char checksum_string[
MBOX_BUF] = {0};
491 snprintf(checksum_string,
MBOX_BUF,
"%s", response + 1);
493 std::vector<std::string> result = split(checksum_string, R
"(\*)");
498 response_checksum = std::stoi(result[1],
nullptr, 16);
507 for (
auto oneByte : result[0])
508 calculated_checksum ^= oneByte;
510 return (calculated_checksum == response_checksum);
516std::vector<std::string> MBox::split(
const std::string &input,
const std::string ®ex)
519 std::regex re(regex);
520 std::sregex_token_iterator
521 first{input.begin(), input.end(), re, -1},
523 return {first, last};
void setDefaultBaudRate(BaudRate newRate)
setDefaultBaudRate Set default baud rate. The default baud rate is 9600 unless otherwise changed by t...
INDI::PropertyText getText(const char *name) 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)
bool isSimulation() const
void addAuxControls()
Add Debug, Simulation, and Configuration options to the driver.
void setState(IPState state)
void apply(const char *format,...) const ATTRIBUTE_FORMAT_PRINTF(2
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 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 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 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
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.
Connection::Serial * serialConnection
virtual bool initProperties() override
Initialize properties initial state and value. The child class must implement this function.
virtual IPState updateWeather() override
updateWeather Update weather conditions from device or service. The function should not change the st...
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
virtual bool Handshake() override
perform handshake with device to check communication
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 const char * getDefaultName() override
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
int tty_read_section(int fd, char *buf, char stop_char, int timeout, int *nbytes_read)
read buffer from terminal with a delimiter
int tty_write(int fd, const char *buf, int nbytes, int *nbytes_written)
Writes a buffer to fd.
void tty_error_msg(int err_code, char *err_msg, int err_msg_len)
Retrieve the tty error message.
Implementations for common driver routines.
#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,...)