From 841e320fe80a6b75546f6e51dde701c30bd72942 Mon Sep 17 00:00:00 2001 From: Nikopol Date: Sat, 12 Oct 2024 19:25:44 +0400 Subject: [PATCH] v0.8: README draft, configuration --- .gitignore | 1 + README.md | 16 +++++++- dnsmonitor.py | 99 ++++++++++++++++++++++++++++++++++++++---------- requirements.txt | 2 + 4 files changed, 97 insertions(+), 21 deletions(-) create mode 100644 .gitignore create mode 100644 requirements.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3507a4c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +config.ini \ No newline at end of file diff --git a/README.md b/README.md index 93aaeab..b238ac6 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,15 @@ # BlockyGrapher - -Query grapher for Blocky DNS Server \ No newline at end of file +Query grapher for Blocky DNS Server +## Install python packages +Debian-based: +```bash +# install system packages +apt install i2c-tools python3-dev python3-pip python3-numpy libfreetype6-dev libjpeg-dev build-essential +# Give user permission to use i2c interface (Replace user with your name). Remember that you need re-login to user after this (You can reboot too if it didn't work for some reason). +usermod -a -G i2c user +# install python packages +pip install -r requirements.txt --break-system-packages +``` +## Finding right port +`i2cdetect -l` can help to find port you need to use. +Schematics for your adapter/board can also help. diff --git a/dnsmonitor.py b/dnsmonitor.py index f804110..d2fc0d2 100644 --- a/dnsmonitor.py +++ b/dnsmonitor.py @@ -120,9 +120,9 @@ def movepoints(points, insertq, restarts, insertr): i += 1 return points, restarts -def parsedata(prev, flaunch): +def extractor(prev, flaunch, url): try: - data = str(urllib.request.urlopen("http://10.0.0.28:4500/metrics").read()).split("\\n") + data = str(urllib.request.urlopen(url).read()).split("\\n") count = 0 i = 0 while data[i] != "# TYPE blocky_query_total counter": @@ -134,7 +134,14 @@ def parsedata(prev, flaunch): else: count += int(re.sub('blocky_query_total{.*?} ', '', data[i])) i += 1 + except urllib.error.URLError as e: + cliout(f"Connection to server failed: {e.reason}", 2) + if flaunch == True: + return -1 + else: + return 0, -1 except: + cliout("Extraction failed.", 2) if flaunch == True: return -1 else: @@ -144,7 +151,7 @@ def parsedata(prev, flaunch): else: return count, count - prev -def drawout(sclpo, maxcanv, failture, restart): +def drawout(sclpo, maxcanv, failture, restart, distance, dots): match device.height: case 32: # todo: backport @@ -168,12 +175,13 @@ def drawout(sclpo, maxcanv, failture, restart): with canvas(device) as draw: # Graph currpoint = 1 - targetpx = 118 + targetpx = 128 - distance while currpoint < len(sclpo): - draw.line((targetpx + 10, 47 - sclpo[currpoint - 1], targetpx, 47 - sclpo[currpoint]), fill="white") - draw.rectangle((targetpx - 1, 47 - sclpo[currpoint] - 1, targetpx + 1, 47 - sclpo[currpoint] + 1), fill="white") + draw.line((targetpx + distance, 47 - sclpo[currpoint - 1], targetpx, 47 - sclpo[currpoint]), fill="white") + if dots == True: + draw.rectangle((targetpx - 1, 47 - sclpo[currpoint] - 1, targetpx + 1, 47 - sclpo[currpoint] + 1), fill="white") currpoint += 1 - targetpx -= 10 + targetpx -= distance # Draw black boxes to make sure that graph will not interfere draw.rectangle((0, 48, 128, 64), fill="black") draw.rectangle((0, 0, 6 * len(str(maxcanv)), 9), fill="black") @@ -193,30 +201,82 @@ def drawout(sclpo, maxcanv, failture, restart): with canvas(device) as draw: draw.text((0,0), "Display not supported", font=smafont, fill="white") -def getdata(oldtotal): - total, query = parsedata(oldtotal, False) +def getdata(oldtotal, url): + total, query = extractor(oldtotal, False, url) + # Server lifetime counter | Difference | Err? | Restarted? if query == -1: + cliout("Extractor finished with error.", 1) return oldtotal, 0, True, False if total < oldtotal: + cliout("Server restart was detected.", 1) return total, 0, False, True return total, query, False, False -def main(): - print("Blocky Graph Monitor for OLED v0.7") - print("(C) Nikopol 2024") +def cliout(data, code): + time = datetime.datetime.now().strftime("%H:%M:%S") + match code: + case 0: + codes = "I" + case 1: + codes = "W" + case 2: + codes = "E" + case 3: + codes = "F" + print(f"[{codes}] [{time}] {data}") +def main(): + cliout("Blocky Graph Monitor for OLED v0.8b", 0) + cliout("(C) Nikopol 2024", 0) + cliout("Init...", 0) + + # vars spagetti + url = "http://127.0.0.1:4500/metrics" + pointscount = 14 + distance = 10 today_last_time = "NaN" last_hrs = "NaN" - i = 0 + i = 1 failture = False restart = False rstate = False + dots = False device.contrast(0) - pointsmap = [0] * 14 + + + # Load config + try: + filedata = open("config.ini").readlines() + except FileNotFoundError: + f = open("config.ini", "x") + f.write("[source]\nurl = http://127.0.0.1:4500/metrics\n[appearance]\npoints = 14\npointsDistance = 10") + f.close() + cliout("config.ini does not exist. Please edit newly created file and start the program.", 3) + exit() + except: + cliout("Failed to read config file. Are permissions correct?", 3) + exit() + while i < len(filedata): + if "url = " in filedata[i]: + url = filedata[i][6:].rstrip() + if "points = " in filedata[i]: + pointscount = int(filedata[i][9:]) + if "pointsDistance = " in filedata[i]: + distance = int(filedata[i][17:]) + if "dots = True" in filedata[i]: + dots = True + i += 1 + i = 0 + cliout("Config load ok", 0) + + pointsmap = [0] * pointscount restartmap = [True] * len(pointsmap) - total = parsedata(0, True) + total = extractor(0, True, url) + + # Show fail on boot time if occurs. if total == -1: failture = True + while True: now = datetime.datetime.now() today_time = now.strftime("%H:%M") @@ -228,7 +288,8 @@ def main(): #if 1: last_hrs = hrs # Grab fresh data - total, query, failture, rstate = getdata(total) + cliout("Extracting data...", 0) + total, query, failture, rstate = getdata(total, url) #print(total) #print(query) # Now write it to (raw) array and move older data @@ -238,18 +299,18 @@ def main(): # also write restart map restart = False while i < len(restartmap): - print(restartmap[i]) if restartmap[i] == True: restart = True i += 1 i = 0 - drawout(sclpo, maxcanv, failture, restart) + cliout(f"Done. Current: {query}", 0) + drawout(sclpo, maxcanv, failture, restart, distance, dots) time.sleep(1) if __name__ == "__main__": try: - #print("\n".join(sys.argv)) + print("[I] Preinit...") device = get_device() regfont = make_font("TerminusTTF-4.49.3.ttf", 22) smafont = make_font("TerminusTTF-4.49.3.ttf", 12) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..47b775c --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +luma.core==2.4.2 +luma.oled==3.13.0 \ No newline at end of file