From 7bbab0dfb7e5c962bba137bde1c9542a1d986066 Mon Sep 17 00:00:00 2001 From: Maxime Boissonneault Date: Thu, 20 Oct 2022 17:42:43 -0400 Subject: [PATCH] highly speed up the check by querying the maker API just once for all devices --- app.py | 110 ++++++++++++++++++++++++++++++--------------------------- 1 file changed, 58 insertions(+), 52 deletions(-) diff --git a/app.py b/app.py index def6d09..8d5204f 100644 --- a/app.py +++ b/app.py @@ -18,14 +18,19 @@ except KeyError as e: print(f"Could not read the environment variable - {e}") +def get_all_devices(): + return requests.get(f"{base_uri}/all?access_token={access_token}") + def get_devices(): return requests.get(f"{base_uri}?access_token={access_token}") @app.route("/info") def info(): + result = get_devices() res = { "status": { - "CONNECTION": "ONLINE" if get_devices().status_code == 200 else "OFFLINE" + "CONNECTION": "ONLINE" if result.status_code == 200 else "OFFLINE", + "CODE": result.status_code }, "config": { "HE_URI": base_uri, @@ -42,58 +47,59 @@ def info(): @app.route("/metrics") def metrics(): - devices = get_devices() - device_attributes = [] - - for device in devices.json(): - device_details = requests.get(f"{base_uri}/{device['id']}?access_token={access_token}").json() - for attrib in device_details['attributes']: - # Is this a metric we should be collecting? - if attrib["name"] in collected_metrics: - # Does it have a "proper" value? - if attrib["currentValue"] is not None: - # If it's a switch, then change from text to binary values - if attrib["name"] == "switch": - if attrib["currentValue"] == "on": - attrib["currentValue"] = 1 - else: - attrib["currentValue"] = 0 - if attrib["name"] == "water": - if attrib["currentValue"] == "dry": - attrib["currentValue"] = 1 - else: - attrib["currentValue"] = 0 - if attrib["name"] == "power": - if attrib["currentValue"] == "on": - attrib["currentValue"] = 1 - elif attrib["currentValue"] == "off": - attrib["currentValue"] = 0 - else: - attrib["currentValue"] = attrib["currentValue"] + devices = get_all_devices() + if devices.status_code == 200: + device_attributes = [] - # Sanitize to allow Prometheus Ingestion - device_name = sanitize(device_details['name']) - device_label = sanitize(device_details['label']) - device_human_label = device_details['label'] - device_type = sanitize(device_details['type']) - device_id = sanitize(device_details['id']) - metric_name = sanitize(attrib['name']) - # Create the dict that holds the data - device_attributes.append({ - "device_name": f"{device_name}", - "device_label": f"{device_label}", - "device_human_label": f"{device_human_label}", - "device_type": f"{device_type}", - "device_id": f"{device_id}", - "metric_name": f"{metric_name}", - "metric_value": f"{attrib['currentValue']}", - "metric_timestamp": time.time()}) - # Create the response - response = make_response(render_template('base.txt', - device_details=device_attributes - )) - # Make sure we return plain text otherwise Prometheus complains - response.mimetype = "text/plain" + for device in devices.json(): + for attrib in device['attributes']: + # Is this a metric we should be collecting? + if attrib in collected_metrics: + value = device['attributes'][attrib] + # Does it have a "proper" value? + if value is not None: + # If it's a switch, then change from text to binary values + if attrib == "switch": + if value == "on": + value = 1 + else: + value = 0 + if attrib == "water": + if value == "dry": + value = 1 + else: + value = 0 + if attrib == "power": + if value == "on": + value = 1 + elif value == "off": + value = 0 + + # Sanitize to allow Prometheus Ingestion + device_name = sanitize(device['name']) + device_label = sanitize(device['label']) + device_human_label = device['label'] + device_type = sanitize(device['type']) + device_id = sanitize(device['id']) + metric_name = sanitize(attrib) + # Create the dict that holds the data + device_attributes.append({ + "device_name": f"{device_name}", + "device_label": f"{device_label}", + "device_human_label": f"{device_human_label}", + "device_type": f"{device_type}", + "device_id": f"{device_id}", + "metric_name": f"{metric_name}", + "metric_value": f"{value}", + "metric_timestamp": time.time()}) + # Create the response + response = make_response(render_template('base.txt', + device_details=device_attributes + )) + # Make sure we return plain text otherwise Prometheus complains + response.mimetype = "text/plain" + else: + response = devices return response def sanitize(inputValue):