From b4571b0c1e5a904286619e6929bbbe157461b1d4 Mon Sep 17 00:00:00 2001 From: "rtrp@factory1" Date: Wed, 27 Jan 2021 21:59:51 +0000 Subject: [PATCH 1/2] create a Systemd service file. This file is used to start the program at startup. It, also, restarts the program if it crashes or throws an exception. The usual scenario which causes the program to crash is the 'max. requests exceeded' exception in the 'requests' module (Python). When that happens, this 'restart' service has a 60 seconds wait period -- which acts as a 'backoff' period. You will need to copy the .service file to the appropriate systemd location, 'daemon-reload' systemctl, enable the service and start the service. You will need to look-up how to do that -- this info. is beyond the scope of this commmit. --- light-meter.service | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 light-meter.service diff --git a/light-meter.service b/light-meter.service new file mode 100644 index 0000000..281b5b7 --- /dev/null +++ b/light-meter.service @@ -0,0 +1,16 @@ +[Unit] +Description=Light-Meter service for Return to Ritherdon project by Nicola Ellis +After=network.service + +[Service] +Type=simple +ExecStart=bash /home/rtrp/repos/light-meter/startup.sh +WorkingDirectory=/home/rtrp/repos/light-meter +StandardOutput=inherit +StandardError=inherit +Restart=always +RestartSec=60 +user=rtrp + +[Install] +WantedBy=multi-user.target From 56e05dceaf14996f11ef48eee4cb4f01ca429777 Mon Sep 17 00:00:00 2001 From: "rtrp@factory1" Date: Fri, 5 Feb 2021 16:54:31 +0000 Subject: [PATCH 2/2] use session to persist REST calls and expand exception handling. Previously, the light-meter was creating a new HTTP request to send every new reading. This now uses a persistant session to reduce the amount of requests made to the server -- and reduce low on the system. The extra exceptions listed and expanded on are mostly for testing. At the time of writing, the system as a whole is hanging at various parts throughout the day and the intention is to monitor the Light Meter to see if any of the new exceptions are the cause (or contributing) to the hanging. The current trains-of-thought at the minute are too many requests (system load too high) and requests not timing out properly. --- cli_meter.py | 33 +++++++++++++++++++-------------- startup.sh | 2 +- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/cli_meter.py b/cli_meter.py index f1ee85f..15018ca 100755 --- a/cli_meter.py +++ b/cli_meter.py @@ -39,7 +39,7 @@ a_pin = 18 # Charges the capacitor. b_pin = 23 # Discharges the capacitor. device_id = platform.node() # For servers logs. - +session = requests.Session() # Persist connection for REST calls. def get_api_url(): # Yes, I know I could do this better. Stop moaning. @@ -56,7 +56,6 @@ def discharge(): GPIO.output(b_pin, False) time.sleep(0.01) # 0.01 -- initial/default value. - def charge_time(): GPIO.setup(b_pin, GPIO.IN) GPIO.setup(a_pin, GPIO.OUT) @@ -67,12 +66,10 @@ def charge_time(): t2 = time.time() return (t2 - t1) * 1000000 - def analog_read(): discharge() return charge_time() - def read_resistance(): n = 20 total = 0 @@ -82,23 +79,20 @@ def read_resistance(): resistance = reading * 6.05 - 939 return resistance - def light_from_r(R): return math.log(1000000.0/R) * 10.0 - def get_timestamp(): return datetime.now().strftime(("%Y-%m-%d %H:%M:%S")) - def push_reading(lvalue): time = get_timestamp() headers = {"content-type": "application/json"} payload = {"reading": int(lvalue), "time": time, "token": "QWERTYuiopasdfghjklzxcvbnm_1234567890"} - # print(payload) # For testing. - res = requests.post(api_url, data=json.dumps(payload), headers=headers) - + print(payload) # For testing. + # res = requests.post(api_url, data=json.dumps(payload), headers=headers) + res = session.post(api_url, data=json.dumps(payload), headers=headers) def update_reading(): light = light_from_r(read_resistance()) @@ -113,11 +107,22 @@ def main(): # pdb.set_trace() # For testing. update_reading() except KeyboardInterrupt: - print("Keyboard Interrupt: quitting program.") - except: - print("Error updating light reading...") + print("[INFO] KEYBOARD INTERRUPT: quitting program.") + except requests.exceptions.ConnectionError: + pause = 60 + time.sleep(60) + print(f"[WARNING] MAX. REQUESTS EXCEEDED: Pausing requests for {pause} seconds...") + pass + except requests.exceptions.Timeout: + t_stamp = datetime.datetime.now() + print(f"[WARNING] TIMEOUT EXCEPTION: Request timed-out at {t_stamp}.") + time.sleep(60) + pass + except Exception as e: + print(f"[ERROR] GENERAL EXCEPTION: {e}") finally: - print("Cleaning up GPIO before closing...") + print("[INFO] Terminating relay.py...") + print("[INFO] Cleaning up GPIO before closing...") GPIO.cleanup() diff --git a/startup.sh b/startup.sh index 0d5d912..9af3fcb 100755 --- a/startup.sh +++ b/startup.sh @@ -20,7 +20,7 @@ # times". -sleep 60 +# sleep 60 logDate=$(date '+%Y-%m-%dT%TZ') logFile="/home/rtrp/logs/startup-logs.txt"