diff --git a/examples/bps.cxx b/examples/bps.cxx index 13e657f..c19b547 100644 --- a/examples/bps.cxx +++ b/examples/bps.cxx @@ -1,7 +1,7 @@ #include <pza/core/client.hxx> #include <pza/core/core.hxx> #include <pza/interfaces/ammeter.hxx> -#include <pza/interfaces/bps_chan_ctrl.hxx> +#include <pza/interfaces/bpc.hxx> #include <pza/interfaces/voltmeter.hxx> static const std::string addr = "localhost"; @@ -35,7 +35,7 @@ int main() return -1; } - auto ctrl = cli->get_interface<pza::itf::bps_chan_ctrl>("default", "Panduza_FakeBps", "channel", 0, "ctrl"); + auto ctrl = cli->get_interface<pza::itf::bpc>("default", "Panduza_FakeBps", "channel", 0, "ctrl"); if (!ctrl) { spdlog::error("ctrl not found"); return -1; @@ -55,7 +55,9 @@ int main() am->register_measure_callback([&]() { spdlog::info("current: {}", am->get_measure()); }); - while (true) - ; + cli->disconnect(); + + //while (true) + // ; return 0; } diff --git a/include/pza/core/device.hxx b/include/pza/core/device.hxx index 83828ed..a08ddf0 100644 --- a/include/pza/core/device.hxx +++ b/include/pza/core/device.hxx @@ -62,6 +62,8 @@ public: [[nodiscard]] std::set<std::string> get_interface_groups() const; + [[nodiscard]] size_t get_interface_groups_count() const; + [[nodiscard]] std::vector<itf_base::s_ptr> get_interfaces() const; private: diff --git a/include/pza/core/interface.hxx b/include/pza/core/interface.hxx index 5463c03..b0f19e5 100644 --- a/include/pza/core/interface.hxx +++ b/include/pza/core/interface.hxx @@ -11,10 +11,17 @@ struct itf_impl; class mqtt_service; class attribute; -struct itf_info; namespace pza { +struct itf_info +{ + std::string bench; + std::string device_name; + std::string name; + std::string type; +}; + // Can't use the name "interface" because it's a reserved keyford for Windows in C++ class itf_base { diff --git a/include/pza/interfaces/bps_chan_ctrl.hxx b/include/pza/interfaces/bpc.hxx similarity index 59% rename from include/pza/interfaces/bps_chan_ctrl.hxx rename to include/pza/interfaces/bpc.hxx index 3347164..320daed 100644 --- a/include/pza/interfaces/bps_chan_ctrl.hxx +++ b/include/pza/interfaces/bpc.hxx @@ -4,19 +4,19 @@ namespace pza::itf { -class bps_chan_ctrl : public itf_base +class bpc : public itf_base { public: - using s_ptr = std::shared_ptr<bps_chan_ctrl>; - using u_ptr = std::unique_ptr<bps_chan_ctrl>; - using w_ptr = std::weak_ptr<bps_chan_ctrl>; + using s_ptr = std::shared_ptr<bpc>; + using u_ptr = std::unique_ptr<bpc>; + using w_ptr = std::weak_ptr<bpc>; - explicit bps_chan_ctrl(mqtt_service *mqtt, itf_info &info); - bps_chan_ctrl(const bps_chan_ctrl &) = delete; - bps_chan_ctrl(bps_chan_ctrl &&) = delete; - bps_chan_ctrl &operator=(const bps_chan_ctrl &) = delete; - bps_chan_ctrl &operator=(bps_chan_ctrl &&) = delete; - ~bps_chan_ctrl() override; + explicit bpc(mqtt_service *mqtt, itf_info &info); + bpc(const bpc &) = delete; + bpc(bpc &&) = delete; + bpc &operator=(const bpc &) = delete; + bpc &operator=(bpc &&) = delete; + ~bpc() override; int set_voltage(double volts); int set_current(double amps); diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index e44163d..4ada899 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -21,7 +21,7 @@ target_sources(${LIBRARY_NAME} interfaces/meter.cxx interfaces/voltmeter.cxx interfaces/ammeter.cxx - interfaces/bps_chan_ctrl.cxx + interfaces/bpc.cxx ${CMAKE_CURRENT_BINARY_DIR}/version.cxx ) diff --git a/source/core/client.cxx b/source/core/client.cxx index 1d980e4..993ac5f 100644 --- a/source/core/client.cxx +++ b/source/core/client.cxx @@ -37,7 +37,7 @@ struct client_impl : mqtt_service { int disconnect(); bool is_connected() const { - return (_paho_client->is_connected()); + return _paho_client->is_connected(); } const std::string &get_addr() const @@ -157,12 +157,15 @@ int client_impl::connect() connOpts.set_keep_alive_interval(interval); connOpts.set_clean_session(true); - if (_paho_client->connect(connOpts)->wait_for(std::chrono::milliseconds(_conn_timeout)) == false) { - spdlog::error("failed to connect to client: {}", _id); + try { + _paho_client->connect(connOpts)->wait_for(std::chrono::milliseconds(_conn_timeout)); + } + catch (const mqtt::exception &exc) { + spdlog::error("Client {} failed to connect on {}:{}", _id, _addr, _port); return -1; } - spdlog::info("connected to {}", _addr); + spdlog::info("connected to {}:{}", _addr, _port); return 0; } @@ -170,8 +173,11 @@ int client_impl::disconnect() { spdlog::debug("Attempting to disconnect from {}...", _addr); - if (_paho_client->disconnect()->wait_for(std::chrono::milliseconds(_conn_timeout)) == false) { - spdlog::error("failed to disconnect from client: {}", _id); + try { + _paho_client->disconnect()->wait_for(std::chrono::milliseconds(_conn_timeout)); + } + catch (const mqtt::exception &exc) { + spdlog::error("Client {} failed to disconnect on {}:{}", _id, _addr, _port); return -1; } spdlog::info("disconnected from {}", _addr); @@ -190,8 +196,11 @@ int client_impl::publish(const std::string &topic, const std::string &payload) int client_impl::publish(mqtt::const_message_ptr msg) { - if (_paho_client->publish(msg)->wait_for(std::chrono::milliseconds(msg_timeout_default_ms)) == false) { - spdlog::error("failed to publish from client: {}", _id); + try { + _paho_client->publish(msg)->wait_for(std::chrono::milliseconds(msg_timeout_default_ms)); + } + catch (const mqtt::exception &exc) { + spdlog::error("Client {} failed to publish", _id); return -1; } spdlog::trace("published message {} to {}", msg->get_payload_str(), msg->get_topic()); @@ -204,11 +213,15 @@ int client_impl::subscribe(const std::string &topic, const std::function<void(mq t = topic::regexify_topic(topic); _listeners[t] = cb; - if (_paho_client->subscribe(topic, 0)->wait_for(std::chrono::seconds(_conn_timeout)) == false) { - spdlog::error("failed to subscribe to topic: {} on client {}", topic, _id); + try { + _paho_client->subscribe(topic, 0)->wait_for(std::chrono::seconds(_conn_timeout)); + } + catch (const mqtt::exception &exc) { + spdlog::error("Client {} failed to subscribe to topic: {}", _id, topic); _listeners.erase(t); return -1; } + spdlog::trace("subscribed to topic: {}", topic); return 0; } @@ -217,8 +230,11 @@ int client_impl::unsubscribe(const std::string &topic) { std::string t; - if (_paho_client->unsubscribe(topic)->wait_for(std::chrono::seconds(_conn_timeout)) == false) { - spdlog::error("failed to unsubscribe from topic: {} on client {}", topic, _id); + try { + _paho_client->unsubscribe(topic)->wait_for(std::chrono::seconds(_conn_timeout)); + } + catch (const mqtt::exception &exc) { + spdlog::error("Client {} failed to unsubscribe from topic: {}", _id, topic); return -1; } spdlog::trace("unsubscribed from topic: {}", topic); @@ -554,3 +570,16 @@ itf_base::s_ptr client::get_interface(const std::string &group, const std::strin return nullptr; return dev->get_interface(interface_name); } + +std::vector<itf_base::s_ptr> client::get_interfaces() const +{ + auto dev = _impl->get_devices(); + std::vector<itf_base::s_ptr> ret; + + for (auto const &elem : dev) { + auto itf = elem->get_interfaces(); + ret.insert(ret.end(), itf.begin(), itf.end()); + } + + return ret; +} diff --git a/source/core/device.cxx b/source/core/device.cxx index 5a97fbf..442b1f7 100644 --- a/source/core/device.cxx +++ b/source/core/device.cxx @@ -58,13 +58,15 @@ struct device_impl { std::vector<itf_base::s_ptr> get_interfaces_in_group(const std::string &group, unsigned int index) const; std::set<std::string> get_interface_groups() const; + size_t get_interface_groups_count() const; + std::vector<itf_base::s_ptr> get_interfaces() const; struct device_info info; std::unordered_map<std::string, std::string> interfaces_scanned; itf::device::s_ptr device_interface = nullptr; - std::unordered_map<std::string, itf_base::s_ptr> interfaces; + std::map<std::string, itf_base::s_ptr> interfaces; }; device_impl::device_impl(mqtt_service *mqtt, const struct device_info &info) @@ -178,6 +180,11 @@ std::vector<itf_base::s_ptr> device_impl::get_interfaces() const return vec; } +size_t device_impl::get_interface_groups_count() const +{ + return get_interface_groups().size(); +} + device::device(mqtt_service *mqtt, struct device_info &info) : _impl(std::make_unique<device_impl>(mqtt, info)) { @@ -281,3 +288,8 @@ std::vector<itf_base::s_ptr> device::get_interfaces() const { return _impl->get_interfaces(); } + +size_t device::get_interface_groups_count() const +{ + return _impl->get_interface_groups_count(); +} diff --git a/source/core/interface.cxx b/source/core/interface.cxx index 515e90a..722f165 100644 --- a/source/core/interface.cxx +++ b/source/core/interface.cxx @@ -16,7 +16,7 @@ static constexpr unsigned int attributes_timeout = 2; itf_impl::itf_impl(mqtt_service *mqtt, itf_info &info) : info(info), - topic_base("pza/" + info.group + "/" + info.device_name + "/" + info.name), + topic_base("pza/" + info.bench + "/" + info.device_name + "/" + info.name), topic_cmd(topic_base + "/cmds/set"), mqtt(mqtt) { diff --git a/source/core/interface.hxx b/source/core/interface.hxx index 8a2fd75..3ba6c69 100644 --- a/source/core/interface.hxx +++ b/source/core/interface.hxx @@ -10,13 +10,6 @@ using namespace pza; -struct itf_info { - std::string group; - std::string device_name; - std::string name; - std::string type; -}; - struct itf_impl { explicit itf_impl(mqtt_service *mqtt, itf_info &info); diff --git a/source/core/interface_factory.cxx b/source/core/interface_factory.cxx index dfb0a14..983f60b 100644 --- a/source/core/interface_factory.cxx +++ b/source/core/interface_factory.cxx @@ -3,7 +3,7 @@ #include <pza/core/device.hxx> #include <pza/interfaces/ammeter.hxx> -#include <pza/interfaces/bps_chan_ctrl.hxx> +#include <pza/interfaces/bpc.hxx> #include <pza/interfaces/device.hxx> #include <pza/interfaces/platform.hxx> #include <pza/interfaces/voltmeter.hxx> @@ -18,7 +18,7 @@ static const std::unordered_map<std::string, interface_factory::factory_function {"platform", allocate_interface<itf::platform>}, {"ammeter", allocate_interface<itf::ammeter>}, {"voltmeter", allocate_interface<itf::voltmeter>}, - {"bpc", allocate_interface<itf::bps_chan_ctrl>}}; + {"bpc", allocate_interface<itf::bpc>}}; itf_base::s_ptr interface_factory::create_interface(mqtt_service *mqtt, const std::string &group, const std::string &device_name, const std::string &name, @@ -27,7 +27,7 @@ itf_base::s_ptr interface_factory::create_interface(mqtt_service *mqtt, const st itf_info info; info.name = name; - info.group = group; + info.bench = group; info.device_name = device_name; info.type = type; diff --git a/source/interfaces/bps_chan_ctrl.cxx b/source/interfaces/bpc.cxx similarity index 66% rename from source/interfaces/bps_chan_ctrl.cxx rename to source/interfaces/bpc.cxx index 5be7ac1..23901f0 100644 --- a/source/interfaces/bps_chan_ctrl.cxx +++ b/source/interfaces/bpc.cxx @@ -1,10 +1,10 @@ -#include <pza/interfaces/bps_chan_ctrl.hxx> +#include <pza/interfaces/bpc.hxx> #include "../core/interface.hxx" using namespace pza::itf; -bps_chan_ctrl::bps_chan_ctrl(mqtt_service *mqtt, itf_info &info) +bpc::bpc(mqtt_service *mqtt, itf_info &info) : itf_base(mqtt, info) { _enable = std::make_shared<attribute>("enable"); @@ -26,15 +26,15 @@ bps_chan_ctrl::bps_chan_ctrl(mqtt_service *mqtt, itf_info &info) _impl->register_attributes({_enable, _voltage, _current}); } -bps_chan_ctrl::~bps_chan_ctrl() = default; +bpc::~bpc() = default; -int bps_chan_ctrl::set_voltage(double volts) +int bpc::set_voltage(double volts) { auto min = _voltage->get_field<double>("min"); auto max = _voltage->get_field<double>("max"); if (volts < min || volts > max) { - spdlog::error("bps_chan_ctrl::set_voltage: voltage out of " + spdlog::error("bpc::set_voltage: voltage out of " "range, min: {}, max: {}, value: {}", min, max, volts); return -1; @@ -42,13 +42,13 @@ int bps_chan_ctrl::set_voltage(double volts) return _voltage->set_field<double>("value", volts); } -int bps_chan_ctrl::set_current(double amps) +int bpc::set_current(double amps) { auto min = _current->get_field<double>("min"); auto max = _current->get_field<double>("max"); if (amps < min || amps > max) { - spdlog::error("bps_chan_ctrl::set_current: current out of " + spdlog::error("bpc::set_current: current out of " "range, min: {}, max: {}, value: {}", min, max, amps); return -1; @@ -56,62 +56,62 @@ int bps_chan_ctrl::set_current(double amps) return _current->set_field<double>("value", amps); } -int bps_chan_ctrl::set_enable(bool enable) +int bpc::set_enable(bool enable) { return _enable->set_field<bool>("value", enable); } -bool bps_chan_ctrl::get_enable() +bool bpc::get_enable() { return _enable->get_field<bool>("value"); } -double bps_chan_ctrl::get_min_voltage() +double bpc::get_min_voltage() { return _voltage->get_field<double>("min"); } -double bps_chan_ctrl::get_max_voltage() +double bpc::get_max_voltage() { return _voltage->get_field<double>("max"); } -double bps_chan_ctrl::get_min_current() +double bpc::get_min_current() { return _current->get_field<double>("min"); } -double bps_chan_ctrl::get_max_current() +double bpc::get_max_current() { return _current->get_field<double>("max"); } -double bps_chan_ctrl::get_preset_voltage() +double bpc::get_preset_voltage() { return _voltage->get_field<double>("value"); } -double bps_chan_ctrl::get_preset_current() +double bpc::get_preset_current() { return _current->get_field<double>("value"); } -unsigned int bps_chan_ctrl::get_num_decimals_voltage() +unsigned int bpc::get_num_decimals_voltage() { return _voltage->get_field<unsigned int>("decimals"); } -unsigned int bps_chan_ctrl::get_num_decimals_current() +unsigned int bpc::get_num_decimals_current() { return _current->get_field<unsigned int>("decimals"); } -void bps_chan_ctrl::register_enable_callback(const std::function<void()> &callback) +void bpc::register_enable_callback(const std::function<void()> &callback) { _enable->register_callback(callback); } -void bps_chan_ctrl::remove_enable_callback(const std::function<void()> &callback) +void bpc::remove_enable_callback(const std::function<void()> &callback) { _enable->remove_callback(callback); }