22 consecutive_failures_(0),
24 subprocess_executor_(nullptr)
37 RCLCPP_ERROR(
getLogger(),
"[CpGcalcliConnection] CpSubprocessExecutor component not found!");
45 getLogger(),
"[CpGcalcliConnection] Initialized with gcalcli path: %s",
54 RCLCPP_DEBUG(
getLogger(),
"[CpGcalcliConnection] Configuration updated");
73 RCLCPP_ERROR(
getLogger(),
"[CpGcalcliConnection] Subprocess executor not available");
80 bool success = (result.exit_code == 0 && !result.timed_out);
90 RCLCPP_INFO(
getLogger(),
"[CpGcalcliConnection] Restarting connection...");
97 const std::string & args,
int timeout_ms)
103 error_result.
stderr_output =
"Subprocess executor not available";
120 command +=
" --calendar \"" + calendar +
"\"";
124 command +=
" " + args;
126 RCLCPP_DEBUG(
getLogger(),
"[CpGcalcliConnection] Executing: %s", command.c_str());
138 auto now = std::chrono::steady_clock::now();
150 RCLCPP_DEBUG(
getLogger(),
"[CpGcalcliConnection] Performing heartbeat check...");
154 bool success = (result.exit_code == 0 && !result.timed_out);
171 RCLCPP_INFO(
getLogger(),
"[CpGcalcliConnection] Connection established");
192 RCLCPP_WARN(
getLogger(),
"[CpGcalcliConnection] Authentication required");
206 getLogger(),
"[CpGcalcliConnection] Connection lost after %d consecutive failures",
228 return output.find(
"Authentication") != std::string::npos ||
229 output.find(
"authorization") != std::string::npos ||
230 output.find(
"oauth") != std::string::npos ||
231 output.find(
"credentials") != std::string::npos ||
232 output.find(
"token") != std::string::npos;
ConnectionState getConnectionState() const
Get current connection state.
std::function< void()> postConnectionLostEvent_
bool isAuthenticationError(const std::string &output) const
Check if output indicates authentication failure.
int consecutive_failures_
smacc2::SmaccSignal< void()> onConnectionLost_
smacc2::SmaccSignal< void()> onAuthenticationRequired_
void restartConnection()
Restart connection after failure.
void update() override
Periodic update for heartbeat (called by SignalDetector)
bool isConnected() const
Check if connected to Google Calendar.
std::function< void()> postAuthenticationRequiredEvent_
smacc2::SmaccSignal< void()> onConnectionRestored_
ConnectionState connection_state_
smacc2::client_core_components::CpSubprocessExecutor * subprocess_executor_
smacc2::client_core_components::SubprocessResult executeGcalcli(const std::string &args, int timeout_ms=30000)
Execute a gcalcli command.
void handleConnectionStateChange(bool success, const std::string &output)
Handle connection state change.
bool checkConnection()
Manually trigger a connection check.
std::function< void()> postConnectionRestoredEvent_
void configure(const GcalcliConfig &config)
Configure the gcalcli connection parameters.
void onInitialize() override
void performHeartbeat()
Perform the heartbeat check.
std::chrono::steady_clock::time_point last_heartbeat_time_
rclcpp::Logger getLogger() const
void requiresComponent(TComponent *&requiredComponentStorage, ComponentRequirement requirementType=ComponentRequirement::SOFT)
SubprocessResult executeCommand(const std::string &command, int timeout_ms=30000)
Execute a command synchronously.
ConnectionState
Connection state for gcalcli.
Configuration for gcalcli client.
std::chrono::seconds heartbeat_interval
How often to check connection health (heartbeat)
std::string gcalcli_path
Path to gcalcli executable (default: "gcalcli" from PATH)
std::vector< std::string > calendars
Calendars to monitor (empty = all calendars)
std::optional< std::string > config_folder
Optional config folder for gcalcli (if not using default)
int max_consecutive_failures
Number of consecutive failures before connection is considered lost.
Result of a subprocess execution.
std::string stderr_output