diff --git a/openc3/lib/openc3/interfaces/interface.rb b/openc3/lib/openc3/interfaces/interface.rb index 58eff1da5f..de6893bfab 100644 --- a/openc3/lib/openc3/interfaces/interface.rb +++ b/openc3/lib/openc3/interfaces/interface.rb @@ -198,14 +198,16 @@ def connect log_dont_log.upcase! period = "#{period.to_f}s" @scheduler.every period do - begin - if log_dont_log == 'DONT_LOG' - cmd(cmd_string, log_message: false) - else - cmd(cmd_string) + if connected?() + begin + if log_dont_log == 'DONT_LOG' + cmd(cmd_string, log_message: false) + else + cmd(cmd_string) + end + rescue Exception => err + Logger.error("Error sending periodic cmd(#{cmd_string}):\n#{err.formatted}") end - rescue Exception => err - Logger.error("Error sending periodic cmd(#{cmd_string}):\n#{err.formatted}") end end end diff --git a/openc3/lib/openc3/microservices/interface_microservice.rb b/openc3/lib/openc3/microservices/interface_microservice.rb index 726479dbcf..219cfa0db8 100644 --- a/openc3/lib/openc3/microservices/interface_microservice.rb +++ b/openc3/lib/openc3/microservices/interface_microservice.rb @@ -613,7 +613,16 @@ def handle_connection_lost(err = nil, reconnect: true) def connect @logger.info "#{@interface.name}: Connecting ..." - @interface.connect + begin + @interface.connect + rescue Exception => error + begin + @interface.disconnect # Ensure disconnect is called at least once on a partial connect + rescue Exception + # We want to report any connect errors, not disconnect in this case + end + raise error + end @interface.state = 'CONNECTED' if @interface_or_router == 'INTERFACE' InterfaceStatusModel.set(@interface.as_json(:allow_nan => true), scope: @scope) diff --git a/openc3/python/openc3/interfaces/interface.py b/openc3/python/openc3/interfaces/interface.py index 6cff465477..495a3578a0 100644 --- a/openc3/python/openc3/interfaces/interface.py +++ b/openc3/python/openc3/interfaces/interface.py @@ -487,15 +487,16 @@ def protocol_cmd(self, cmd_name, *cmd_args, read_write="READ_WRITE", index=-1): return handled def run_periodic_cmd(self, log_dont_log, cmd_string): - try: - if log_dont_log == "DONT_LOG": - cmd(cmd_string, log_message=False) - else: - cmd(cmd_string) - except Exception as error: - Logger.error( - f"Error sending periodic cmd({cmd_string}):\n{traceback.format_exception(error)}" - ) + if self.connected(): + try: + if log_dont_log == "DONT_LOG": + cmd(cmd_string, log_message=False) + else: + cmd(cmd_string) + except Exception as error: + Logger.error( + f"Error sending periodic cmd({cmd_string}):\n{traceback.format_exception(error)}" + ) def scheduler_thread_body(self): next_time = time.time() diff --git a/openc3/python/openc3/microservices/interface_microservice.py b/openc3/python/openc3/microservices/interface_microservice.py index c227b4735a..8bf5f5343b 100644 --- a/openc3/python/openc3/microservices/interface_microservice.py +++ b/openc3/python/openc3/microservices/interface_microservice.py @@ -692,6 +692,16 @@ def handle_connection_lost(self, error=None, reconnect=True): def connect(self): self.logger.info(f"{self.interface.name}: Connecting :") + + try: + self.interface.connect() + except RuntimeError as error: + try: + self.interface.disconnect() # Ensure disconnect is called at least once on a partial connect + except RuntimeError: + pass # We want to report any connect errors, not disconnect in this case + raise error + self.interface.connect() self.interface.state = "CONNECTED" if self.interface_or_router == "INTERFACE":