## -*- coding: utf-8 -*-
<%!
import socket
import time
import os
import platform
import sys
import gc
import multiprocessing
import subprocess
import re
import threading
import random
from importlib.metadata import metadata, version
import kaithem
from scullery import workers as sworkers
from kaithem.api.midi import list_midi_inputs
from kaithem.src import unitsofmeasure
from kaithem.src import systasks
from kaithem.src import settings_overrides
from icemedia import sound_player as sound
from kaithem.src import util
from kaithem.src import astrallibwrapper as sky
from kaithem.src import workers
from kaithem.src.config import config
try:
__version__ = metadata("kaithem").get("Version", version("kaithem"))
except Exception as e:
__version__ = str(e)
def sensors():
try:
if util.which("sensors"):
return subprocess.check_output("sensors").decode("utf8")
else:
return '"sensors" command failed(lm_sensors not available)'
except Exception:
return "sensors call failed"
if os.name != "nt":
import fcntl
import struct
def get_interface_ip(ifname):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
return socket.inet_ntoa(fcntl.ioctl(s.fileno(), 0x8915, struct.pack('256s',
ifname[:15].encode('utf-8') ))[20:24])
def get_user():
try:
return subprocess.check_output(['whoami'])
except Exception:
return ""
def get_user():
try:
return subprocess.check_output(['whoami'])
except Exception:
return ""
def get_lan_ip():
ip = socket.gethostbyname(socket.gethostname())
if os.name != "nt":
interfaces = [
"eth0",
"eth1",
"eth2",
"wlp2s0",
"wlan0",
"wlan1",
"wifi0",
"wlo0",
"wlo1",
"ath0",
"ath1",
"ppp0",
"tun0",
]
s='unknown'
for ifname in interfaces:
try:
ip = get_interface_ip(ifname)
s = ifname
if not ip.startswith("127."):
break
except IOError:
pass
return ip,s
def list_ips():
ips={}
if os.name != "nt":
interfaces = [
"eth0",
"eth1",
"eth2",
"wlp2s0",
"wlan0",
"wlan1",
"wifi0",
"wlo0",
"wlo1",
"ath0",
"ath1",
"ppp0",
"tun0",
]
for ifname in interfaces:
try:
ips[ifname]=[get_interface_ip(ifname),None]
except IOError:
pass
try:
import psutil
for interface, addrs in psutil.net_if_addrs().items():
v4 = None
v6 = None
for addr in addrs:
if addr.family == socket.AF_INET:
v4 = addr.address
elif addr.family == socket.AF_INET6:
v6 = addr.address
ips[interface] = [v4, v6]
except ImportError:
pass
return sorted(ips.items())
lanip =get_lan_ip()
%>
<%
try:
import psutil
except Exception:
psutil=None
try:
partitions = psutil.disk_partitions(all=True)
disks = {}
for p in partitions:
if p.device.startswith("/dev") or p.device=='tmpfs':
if 'rw' in p.opts.split(","):
id = p.device+" at " + p.mountpoint
try:
disks[p.device, p.mountpoint] = psutil.disk_usage(p.mountpoint)
except OSError:
pass
except Exception:
print(traceback.format_exc())
disks = {}
%>
<%include file="/pageheader.html"/>
About Kaithem
About
${config['about_box_banner']}
Version: ${__version__|h}
LAN access QR(${lanip[1]}):
Disks
|
Device
|
Mounted
|
Size
|
Full
|
%for i in sorted(list(disks.keys())):
| ${i[0]|h} |
${i[1]|h} |
${unitsofmeasure.si_format_number(disks[i].total)|h} |
%if disks[i].percent<75:
${disks[i].percent|h}% |
%elif disks[i].percent<90:
${disks[i].percent|h}% |
%else:
${disks[i].percent|h}% |
%endif
%endfor
Time/Weather
| Moon Age(Days, approx) |
${sky.moon_age()} |
| Moon Illumination(approx) |
${sky.moon_illumination()}% |
IP Data
| HTTPS(Secure) Port |
${config['https_port']} |
| HTTP(Unsecure) Port |
${config['http_port']} |
Addresses
| Device | IPv4 | IPv6 |
%for i in list_ips():
| ${i[0]} |
${i[1][0]} |
${i[1][1]} |
%endfor
Current Statistics
| Process Started |
${time.strftime(settings_overrides.get_val('core/strftime_string'),time.localtime(systasks.systemStarted))} |
| Thread pool latency |
%try:
${round(sworkers.testLatency()*1000,3)}ms
%except Exception as e:
${e|h}
%endtry
|
| Uncollectable garbage cycles |
${len(gc.garbage)} |
|
Uptime
|
${unitsofmeasure.format_time_interval(time.time()-systasks.systemStarted,4)}
|
<%
try:
load = os.getloadavg()
load = (round(load[0],2), round(load[1],2),round(load[2],2))
except Exception:
load = "Load average not availible on non UNIX-like systems."
try:
f = util.readfile("/proc/meminfo")
total = int(re.search("MemTotal.*?([0-9]+)",f).group(1))
free = int(re.search("MemFree.*?([0-9]+)",f).group(1))
cache = int(re.search("Cached.*?([0-9]+)",f).group(1))
used = round(((total - (free+cache))/1000.0),2)
usedp = round((1-(free+cache)/float(total))*100,2)
total = round(total/1024,2)
except Exception as e:
total=used=usedp = "Unavailable"
def makecpuspan(num):
if num> multiprocessing.cpu_count():
return 'style="color:red;"'
else:
return ""
%>
| System Load Average(UNIX only) |
1 min: ${load[0]} 5 min: ${load[1]}
15 min: ${load[2]}
|
| Memory Used By All Processes(UNIX only) |
${used} MB (${usedp}%) |
| Tasks in thread pool queue |
${sworkers.waitingtasks()} |
System Info
| CPU Type |
${platform.machine()|h}
|
| CPU Count |
${multiprocessing.cpu_count()|h}
|
| CPU |
${platform.processor()|h} |
| Total Availible RAM(UNIX Only) |
${total|h} MB |
| OS Type |
${platform.system()|h} |
| OS Version |
${platform.release()|h} |
| Python Version |
${platform.python_version()|h} |
| Audio Backend |
${sound.backend.backendname|h} |
| System Time Zone |
${time.tzname[0]|h} |
Python Path
%for i in sys.path:
- ${i|h}
%endfor
MIDI Inputs (JACK)
%for i in list_midi_inputs(force_update=True):
- ${i|h}
%endfor
lm_sensors output(Requires lm_sensors to be installed)
${sensors()|h}
<%
def module_version(m, name):
try:
return metadata(name)["Version"]
except Exception:
pass
try:
v = version(name)
if v:
return v
except Exception:
pass
try:
if hasattr(m,"__version__"):
return m.__version__
if hasattr(m,"version"):
if isinstance(m.version, (str,int,float,tuple)):
return m.version
if hasattr(m,"VERSION"):
return m.VERSION
if hasattr(m,"__VERSION__"):
return m.__VERSION__
except Exception as e:
return None
return None
%>
Imported Module Versions
Click to expand
| Module |
Version |
%for i in sorted(sys.modules):
%if module_version(sys.modules[i], i):
| ${i|h} |
${module_version(sys.modules[i], i)|h} |
%endif
%endfor
<%include file="/pagefooter.html"/>