From accc4219cf4ac0a7aa68c420b3b75ab93ae95f06 Mon Sep 17 00:00:00 2001 From: Jannik Beyerstedt Date: Mon, 17 Apr 2023 20:49:53 +0200 Subject: [PATCH] WIP: Add network information --- Readme.md | 4 +++ node.json | 8 +++-- node.lua | 58 ++++++++++++++++++++++++++++++++- package.json | 8 ++--- service | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 160 insertions(+), 8 deletions(-) create mode 100644 Readme.md diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..5e9152d --- /dev/null +++ b/Readme.md @@ -0,0 +1,4 @@ +# info-beamer testcard +Screen test card with additional information for https://info-beamer.com. + +This is a modified version of https://git.franzi.business/kunsi/infobeamer-testcard, which adds network connectivity information (taken from the [Screen Installation Instructions](https://github.com/info-beamer/package-installation-help) package). diff --git a/node.json b/node.json index 2ebd077..f4dc52f 100644 --- a/node.json +++ b/node.json @@ -1,7 +1,9 @@ { - "name": "c3voc testcard", + "name": "Screen Testcard", "options": [], "permissions": { - "network": "Needs to fetch device info from info-beamer api" + "network": "Needs to fetch device info from info-beamer api", + "unboxed": "Needs access to the device configuration", + "run-as-root": "Needs access to /sd/config" } -} +} \ No newline at end of file diff --git a/node.lua b/node.lua index 80ba863..93e3802 100644 --- a/node.lua +++ b/node.lua @@ -1,3 +1,4 @@ +node.alias "testcard" util.init_hosted() local json = require "json" @@ -19,6 +20,14 @@ gl.setup(NATIVE_WIDTH, NATIVE_HEIGHT) card = resource.load_image("testcard.png") font = resource.load_font("vera.ttf") +local v = {} + +util.data_mapper{ + ["update/(.*)"] = function(key, val) + v[key] = val + end +} + function node.render() gl.clear(0,0,0,1) @@ -27,7 +36,7 @@ function node.render() -- upper: 623 -- lower: 707 - upper_text = "C3VOC: " .. description + upper_text = "CCC: " .. description if location == nil or location == '' then lower_text = "Serial " .. serial @@ -40,4 +49,51 @@ function node.render() lower_width = font:width(lower_text, 20) font:write(960-(lower_width/2), 679, lower_text, 20, 1,1,1,1) + + -- TODO + local size, k_x, v_x, y + + size = math.floor(HEIGHT/20) + y = 30+size*6 + k_x, v_x = 30, 30+font:width("XXXXXXXXXXXXXXXX", size) + util.draw_correct(logo, 30, 30, WIDTH/2-30, 30+size*5) + gray:draw(WIDTH/2-1, 0, WIDTH/2+1, HEIGHT) + + local function key(str) + font:write(k_x, y, str, size, 1,1,1,.5) + end + local function val(str, col) + col = col or {1,1,1,.5} + font:write(v_x, y, str, size, unpack(col)) + y = y + size*1.1 + end + + if v.network then + key "Network config" + val(v.network) + end + + if v.ethip then + key "Ethernet IPv4" + val(v.ethip) + end + + if v.wlanip then + key "WiFi IPv4" + val(v.wlanip) + end + + if v.gw then + key "Gateway" + val(v.gw) + end + + if v.online then + key "Online status" + local col = {1,0,0,1} + if v.online == "online" then + col = {0,1,0,1} + end + val(v.online, col) + end end diff --git a/package.json b/package.json index e6b3e79..35493b8 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { - "name": "c3voc testcard", - "author": "Kunsi ", + "name": "infobeamer-testcard", + "author": "Jannik Beyerstedt ", "desc": "testcard", - "repository": "https://git.kunsmann.eu/kunsi/icinga2beamer", + "repository": "https://git.beyerstedt.de/jannik/infobeamer-testcard", "nesting": { "parents": [ "top-level" @@ -17,4 +17,4 @@ "support": "no", "info": "Needs to fetch information about itself from info-beamer api" } -} +} \ No newline at end of file diff --git a/service b/service index fd5c80f..50b6230 100644 --- a/service +++ b/service @@ -1,12 +1,22 @@ #!/usr/bin/python +import os import sys +import fcntl +import socket +import struct +import requests import time import traceback +from functools import partial +from heapq import heappush, heapreplace from hosted import api, node +sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + + def fetch_info(): info = api.device_info.get() print >> sys.stderr, info @@ -18,10 +28,90 @@ def fetch_info(): ) +def send(key, val): + sys.stderr.write("sending %s->%s\n" % (key, val)) + sock.sendto('testcard/update/%s:%s' % (key, val), ('127.0.0.1', 4444)) + + +def get_default_gateway(): + with open("/proc/net/route") as fh: + for line in fh: + fields = line.strip().split() + if fields[1] != '00000000' or not int(fields[3], 16) & 2: + continue + return socket.inet_ntoa(struct.pack("I', fcntl.ioctl( + s.fileno(), 0x891b, struct.pack('256s', ifname))[20:24])[0] + # Remember: not everything has to be performance optimal :-) + mask = bin(mask)[2:].count('1') + return "%s/%d" % (ip, mask) + except IOError: + return "" + except: + return None + + +def check_network(): + return os.path.exists('/sd/config/network') and "static" or "dhcp" + + +def check_internet(): + try: + r = requests.get("http://ping.infobeamer.com/ping", timeout=10, headers={ + 'User-Agent': 'info-beamer syncer/network-check', + }) + r.raise_for_status() + if r.content == "pong": + return "online" + else: + return "filtered" + except: + traceback.print_exc() + return "offline" + + +tests = [ + (1, "ethip", partial(get_ipv4, "eth0")), + (1, "wlanip", partial(get_ipv4, "wlan0")), + (1, "gw", get_default_gateway), + (10, "online", check_internet), + (5, "network", check_network), +] + +q = [] +now = time.time() +for interval, key, val_fn in tests: + heappush(q, (now, (interval, key, val_fn))) + + +def run_next_test(): + now = time.time() + t, test = q[0] + if now < t: + return False + interval, key, val_fn = test + heapreplace(q, (now + interval, test)) + val = val_fn() + if val is not None: + send(key, val) + return True + + if __name__ == "__main__": while 1: try: fetch_info() + if not run_next_test(): + time.sleep(0.2) except: traceback.print_exc() finally: