From d4e2e17bef9dc278b825dfbce268612633d016af Mon Sep 17 00:00:00 2001 From: Todd Saylor Date: Sat, 24 Apr 2021 13:43:46 -0700 Subject: [PATCH] Work around a 'stuck' legacy Eagle by sending a get_historical_data request and adding a delay, with logging Notes: When the legacy Eagle returns a 503 response with text "Timeout waiting for response", through trial-and-error I discovered that it is possible to get things running again by sending the get_historical_data request to the cgi_manager endpoint (as used by the web interface). After sending this request and waiting several seconds, the requests used by this client will typically begin working again. This change automates that workaround process. --- uEagle/uEagle.py | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/uEagle/uEagle.py b/uEagle/uEagle.py index 142348d..5ef7d44 100644 --- a/uEagle/uEagle.py +++ b/uEagle/uEagle.py @@ -1,5 +1,6 @@ import json import time +import logging import requests from struct import unpack, pack @@ -10,6 +11,8 @@ {0!s}\n JSON''' +_LOGGER = logging.getLogger(__name__) + # Options SAFETY_ON = True @@ -60,6 +63,8 @@ def post_cmd(self, command, **kws): response = requests.post(self.addr, headers=self._headers, data=post_data) + if response.status_code == 503: + response = ATTEMPT_TO_UNSTICK_EAGLE(self, command, response.text, **kws) response_text = TEMP_RESPONSE_FIX(response.text) data = json.loads(response_text) @@ -184,6 +189,49 @@ def TEMP_RESPONSE_FIX(s): return '{' + s + '}' return s +def ATTEMPT_TO_UNSTICK_EAGLE(self, command, orig_response, **kws): + ''' + By the process of trial and error... + It seems that sending a 'get_historical_data' request using the alternate + cgi_manager endpoint (same endpoint used by the web pages), we can + "unstick" the server and in a few seconds it will start responding to + requests again. + ''' + + # First we do a short pause and simply try again + time.sleep(1) + post_data = self.make_cmd(command, **kws) + response = requests.post(self.addr, + headers=self._headers, + data=post_data) + if response.status_code == 200: + _LOGGER.warning("Eagle success after retry (original response: %s)", orig_response) + return response + + # Try to unstick by issuing the same get_historical_data command used by the web page + post_data = self.make_cmd("get_historical_data", **kws) + alt_address = self.addr.replace("post_manager", "cgi_manager") + response = requests.post(alt_address, + headers=self._headers, + data=post_data) + + if response.status_code == 200: + # If that was successful (but probably an empty response), wait a bit for it to recover + time.sleep(15) # Eagle seems to take some time to 'wake up' from the bad state + # Re-issue the original command + post_data = self.make_cmd(command, **kws) + response = requests.post(self.addr, + headers=self._headers, + data=post_data) + if response.status_code == 200: + _LOGGER.warning("Eagle 'unstick' successful: %s (original response: %s)", response.text, orig_response) + else: # Note: at this point it is possible it's working again but requires a bit more time + _LOGGER.error("Eagle 'unstick' failed: %s [%s], (original response: %s)", response.text, response.status_code, orig_response) + else: + _LOGGER.error("Eagle 'unstick' attempt failed: %s [%s]", response.text, response.status_code) + + return response + #notes #More recent API (1.1) supports command list_network ##list_network does not return JSON