44std::vector<std::string>
split(
const std::string &input,
const std::string ®ex)
48 std::sregex_token_iterator
49 first{input.begin(), input.end(), re, -1},
60 int nbytes_written = 0, nbytes_read = 0;
61 tcflush(m_PortFD, TCIOFLUSH);
63 std::string output =
command.dump();
65 if ( (tty_rc =
tty_write(m_PortFD, output.c_str(), output.length(), &nbytes_written)) !=
TTY_OK)
67 char errorMessage[
MAXRBUF] = {0};
69 LOGF_ERROR(
"Serial write error: %s", errorMessage);
74 if (response ==
nullptr)
77 char read_buf[DRIVER_LEN];
80 memset(read_buf, 0,
sizeof(read_buf));
81 if ( (tty_rc =
tty_read_section(m_PortFD, read_buf, DRIVER_STOP_CHAR, DRIVER_TIMEOUT, &nbytes_read)) !=
TTY_OK)
83 char errorMessage[
MAXRBUF] = {0};
85 LOGF_ERROR(
"Serial write error: %s", errorMessage);
89 while (strncmp(read_buf,
"ERR:", 4) == 0 && (
LOGF_WARN(
"%s", read_buf),
true));
95 if (strstr(read_buf,
"Error:"))
100 *response = json::parse(read_buf)[
"res"];
114 std::string response;
115 if (
get(
type, parameter, response))
117 sscanf(response.c_str(),
"%lf", &value);
138 json jsonRequest = {{parameter,
""}};
159 return isDone ==
"done";
164 const json &command, T *response)
170 jsonRequest = {{
"req", {{
type, {{node,
command}}}}}};
171 if (response ==
nullptr)
180 std::string flat =
command.flatten().items().begin().key();
181 std::vector<std::string> keys =
split(flat,
"/");
189 if (jsonResponse[
type].contains(key))
191 else if (jsonResponse[
type].contains(
"ERROR"))
193 std::string error = jsonResponse[
type][
"ERROR"];
200 if (jsonResponse[
type][node].contains(key))
201 jsonResponse[
type][node][key].
get_to(*response);
202 else if (jsonResponse[
type][node].contains(
"ERROR"))
204 std::string error = jsonResponse[
type][node][
"ERROR"];
215 LOGF_ERROR(
"Failed Request: %s\nResponse: %s\nException: %s id: %d", jsonRequest.
dump().c_str(),
216 jsonResponse.
dump().c_str(),
241 std::string response;
243 return response ==
"done";
303 isDetected = detected == 1;
317 constexpr int32_t INVALID_POSITION = std::numeric_limits<int32_t>::min();
318 int32_t steps = INVALID_POSITION;
321 steps = INVALID_POSITION;
329 "Ignoring invalid negative focuser position %d.", steps);
333 position =
static_cast<uint32_t
>(steps);
361 return status[
"BUSY"] == 1;
406 versions[
"SWAPP"].
get_to(response);
477 auto name = std::string(
"RUNPRESET_") + std::to_string(index);
478 auto user = std::string(
"user_") + std::to_string(index);
480 json preset = {{
"RP_NAME", user},
498 json jsonRequest = {{
"req", {{
"get", {{
"MOT1", { {
"FnRUN_ACC",
""},
499 {
"FnRUN_DEC",
""}, {
"FnRUN_SPD",
""}, {
"FnRUN_CURR_ACC",
""},
500 {
"FnRUN_CURR_DEC",
""}, {
"FnRUN_CURR_SPD",
""}, {
"FnRUN_CURR_HOLD",
""}, {
"HOLDCURR_STATUS",
""}
512 jsonResponse[
"get"][
"MOT1"][
"FnRUN_ACC"].
get_to(rates.
accRate);
513 jsonResponse[
"get"][
"MOT1"][
"FnRUN_DEC"].
get_to(rates.
decRate);
522 jsonResponse[
"get"][
"MOT1"][
"HOLDCURR_STATUS"].
get_to(status);
523 motorHoldActive = ( status == 1 );
585 bool busy = (status[
"BUSY"] == 1);
588 status[
"MST"].get_to(mst);
592 bool motorStopped = mst.
empty() || (mst ==
"stop");
593 return busy || !motorStopped;
610 json jsonRequest = {{
"req", {{
"srv", {{
"GET_MODEL_SUBMODEL",
""}}}}}};
617 std::string response;
618 jsonResponse[
"srv"][
"GET_MODEL_SUBMODEL"].
get_to(response);
620 size_t subModelPos = response.find(
"SubModel = ");
621 if (subModelPos != std::string::npos)
624 size_t commaPos = response.find(
",", subModelPos);
625 if (commaPos != std::string::npos)
626 submodel = response.substr(subModelPos, commaPos - subModelPos);
628 submodel = response.substr(subModelPos);
652 json jsonRequest = {{
"req", {{
"get", {{
"MOT1", { {
"FnRUN_ACC",
""},
653 {
"FnRUN_DEC",
""}, {
"FnRUN_SPD",
""}, {
"FnRUN_CURR_ACC",
""},
654 {
"FnRUN_CURR_DEC",
""}, {
"FnRUN_CURR_SPD",
""}, {
"FnRUN_CURR_HOLD",
""}, {
"HOLDCURR_STATUS",
""}
666 jsonResponse[
"get"][
"MOT1"][
"FnRUN_ACC"].
get_to(rates.
accRate);
667 jsonResponse[
"get"][
"MOT1"][
"FnRUN_DEC"].
get_to(rates.
decRate);
676 jsonResponse[
"get"][
"MOT1"][
"HOLDCURR_STATUS"].
get_to(status);
677 motorHoldActive = (status == 1);
809 return m_Communication->set(
GENERIC_NODE, {{
"ARCO", enabled ? 1 : 0}});
818 if (m_Communication->get(
GENERIC_NODE,
"ARCO", enabled))
832 command = {{
"POSITION_DEG",
""}};
835 command = {{
"POSITION_ARCSEC",
""}};
838 command = {{
"POSITION_STEP",
""}};
842 return m_Communication->genericRequest(
"MOT2",
"get", command, &value);
854 command = {{
"MOVE_ABS", {{
"DEG", value}}}};
857 command = {{
"MOVE_ABS", {{
"ARCSEC", value}}}};
860 command = {{
"MOVE_ABS", {{
"STEP",
static_cast<int>(value)}}}};
864 return m_Communication->command(
MOT_2, command);
876 command = {{
"SYNC_POS", {{
"DEG", value}}}};
879 command = {{
"SYNC_POS", {{
"ARCSEC", value}}}};
882 command = {{
"SYNC_POS", {{
"STEP",
static_cast<int>(value)}}}};
886 return m_Communication->command(
MOT_2, command);
895 if (m_Communication->get(
MOT_2,
"STATUS", status))
897 return status[
"BUSY"] == 1;
907 return m_Communication->get(
MOT_2,
"STATUS", status);
915 return m_Communication->command(
MOT_2, {{
"MOT_STOP",
""}});
923 return m_Communication->set(
MOT_2, {{
"CAL_STATUS",
"exec"}});
932 if (m_Communication->get(
MOT_2,
"CAL_STATUS", value))
934 return value ==
"exec";
944 return m_Communication->set(
MOT_2, {{
"REVERSE", enabled ? 1 : 0}});
953 if (m_Communication->get(
MOT_2,
"REVERSE", value))
965 return m_Communication->get(
GENERIC_NODE,
"ARCO_SN", response);
980 return m_Communication->get(
GENERIC_NODE,
"MODNAME", model);
989 json jsonRequest = {{
"req", {{
"get", {{
"MOT2",
""}}}}}};
990 return m_Communication->sendRequest(jsonRequest, &info);
1006 return m_Communication->get(
GENERIC_NODE,
"MODNAME", model);
1014 json jsonRequest = {{
"req", {{
"set", {{
"LIGHT", enabled ? 1 : 0}}}}}};
1015 return m_Communication->sendRequest(jsonRequest);
1025 if (m_Communication->get(
GENERIC_NODE,
"LIGHT", value))
1036 return m_Communication->get(
GENERIC_NODE,
"MAX_BRIGHTNESS", value);
1044 return m_Communication->set(
GENERIC_NODE, {{
"BRIGHTNESS", value}});
1052 return m_Communication->get(
GENERIC_NODE,
"BRIGHTNESS", value);
1068 return m_Communication->get(
GENERIC_NODE,
"MODNAME", model);
1076 return m_Communication->get(
MOT_1,
"STATUS", status);
1100 return m_Communication->set(
MOT_1, {{
"POSITION", value}});
1108 return m_Communication->get(
MOT_1,
"POSITION", value);
1116 return m_Communication->command(
MOT_1, {{
"MOT_STOP",
""}});
1124 return m_Communication->command(
MOT_1, {{
"CAL_ALTO",
"Init"}});
1132 return m_Communication->command(
MOT_1, {{
"CAL_ALTO", fast ?
"Close_Fast" :
"Close_Slow"}});
1140 return m_Communication->command(
MOT_1, {{
"CAL_ALTO", fast ?
"Open_Fast" :
"Open_Slow"}});
1148 return m_Communication->command(
MOT_1, {{
"CAL_ALTO",
"StoreAsClosedPos"}});
1156 return m_Communication->command(
MOT_1, {{
"CAL_ALTO",
"StoreAsMaxOpenPos"}});
bool close(bool fast=false)
bool storeClosedPosition()
bool getPosition(uint8_t &value)
bool getModel(std::string &model)
bool setPosition(uint8_t value)
bool open(bool fast=false)
bool getStatus(json &status)
bool setEnabled(bool enabled)
bool getModel(std::string &model)
bool getStatus(json &status)
bool getMotorInfo(json &info)
bool moveAbsolutePoition(Units unit, double value)
Arco(const std::string &name, int port)
bool sync(Units unit, double value)
bool getSerialNumber(std::string &response)
bool getAbsolutePosition(Units unit, double &value)
bool reverse(bool enabled)
bool getFirmwareVersion(std::string &response)
bool command(NodeType type, const json &jsonCommand)
bool genericRequest(const std::string &node, const std::string &type, const json &command, T *response=nullptr)
bool sendRequest(const json &command, json *response=nullptr)
bool getStringAsDouble(NodeType type, const std::string ¶meter, double &value)
getStringAsDouble Same as get, but it receives a string and scan it for double.
bool get(NodeType type, const std::string ¶meter, T &value)
bool set(NodeType type, const json &value)
bool setBacklash(uint32_t steps)
bool getBacklash(uint32_t &steps)
bool getVoltageUSB(double &value)
bool getModel(std::string &model)
bool getVoltage12v(double &value)
std::unique_ptr< Communication > m_Communication
bool getAbsolutePosition(uint32_t &position)
bool getExternalTemp(double &value)
bool isHallSensorDetected(bool &isDetected)
bool getSerialNumber(std::string &response)
Focuser(const std::string &name, int port)
bool getFirmwareVersion(std::string &response)
bool setBacklash(uint32_t steps)
bool getCurrentSpeed(uint32_t &speed)
bool getMotorTemp(double &value)
bool getMaxPosition(uint32_t &position)
bool getStatus(json &status)
bool getBacklash(uint32_t &steps)
bool goAbsolutePosition(uint32_t position)
bool getMaxBrightness(uint16_t &value)
bool getModel(std::string &model)
bool setLightEnabled(bool enabled)
bool getBrightness(uint16_t &value)
bool setBrightness(uint16_t value)
bool getMotorSettings(struct MotorRates &rates, struct MotorCurrents ¤ts, bool &motorHoldActive)
bool setMotorCurrents(const MotorCurrents ¤ts)
bool setMotorHold(bool hold)
bool applyMotorPreset(const std::string &name)
bool setMotorUserPreset(uint32_t index, const MotorRates &rates, const MotorCurrents ¤ts)
bool storeAsMaxPosition()
bool storeAsMinPosition()
bool getModel(std::string &model)
bool setMotorRates(const MotorRates &rates)
bool storeAsMinPosition()
bool moveOut(uint32_t steps)
bool getModel(std::string &model)
bool setRecoveryDelay(int32_t delay)
bool setMotorRates(const MotorRates &rates)
bool getSubModel(std::string &submodel)
bool moveIn(uint32_t steps)
bool storeAsMaxPosition()
bool applyMotorPreset(const std::string &name)
bool initCalibrationSemiAuto()
bool goAbsolutePosition(uint32_t position)
bool getMotorSettings(MotorRates &rates, MotorCurrents ¤ts, bool &motorHoldActive)
bool setMotorHold(bool hold)
bool getRecoveryDelay(int32_t &delay)
bool getAbsolutePosition(uint32_t &position)
bool startAutoCalibration()
bool setMotorCurrents(const MotorCurrents ¤ts)
a class to store JSON values
ValueType & get_to(ValueType &v) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >(), v)))
get a value (explicit)
string_t dump(const int indent=-1, const char indent_char=' ', const bool ensure_ascii=false, const error_handler_t error_handler=error_handler_t::strict) const
serialization
bool empty() const noexcept
checks whether the container is empty.
bool contains(const typename object_t::key_type &key) const
check the existence of an element in a JSON object
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 int id
the id of the exception
const char * what() const noexcept override
returns the explanatory string
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_WARN(fmt,...)
#define LOGF_DEBUG(fmt,...)
#define LOGF_ERROR(fmt,...)
#define DEBUGFDEVICE(device, priority, msg,...)
std::vector< std::string > split(const std::string &input, const std::string ®ex)