#include "../constants.h" #include "heart.h" #include #include "../dixon_node_state.h" namespace cardio { Heart::Heart() : _lastBeat(std::chrono::steady_clock::now()), chip_(std::string("/dev/") + dixon::GPIO_CHIP_NAME), isOn_(false), request_(get_line_request(chip_, dixon::GPIO_HEART_PIN)), logger_("Heart") { } void Heart::beat() { if (const auto nodeStatus = DixonNodeState::instance().getNodeStatus(); nodeStatus == NodeStatus::Stopped || nodeStatus == NodeStatus::Stopping) return; const auto now = std::chrono::steady_clock::now(); if (const auto elapsed = std::chrono::duration_cast (now - _lastBeat); elapsed.count() >= 500) { isOn_ = !isOn_; const auto val = isOn_ ? gpiod::line::value::ACTIVE : gpiod::line::value::INACTIVE; request_.set_value(dixon::GPIO_HEART_PIN, val); _lastBeat = now; if (isOn_) { logger_.debug("Heart::beat()"); } } } void Heart::stop() { logger_.info("Stopping heart."); isOn_ = false; request_.set_value(dixon::GPIO_HEART_PIN, gpiod::line::value::INACTIVE); logger_.info("Stopped heart."); } gpiod::line_request Heart::get_line_request(gpiod::chip& chip, const unsigned int lineOffset) { const auto settings = gpiod::line_settings() // Force it to a known state immediately on acquisition .set_output_value(gpiod::line::value::INACTIVE) .set_direction(gpiod::line::direction::OUTPUT); return chip.prepare_request() .set_consumer("dixon-robot") .add_line_settings(lineOffset, settings) .do_request(); } }