mirror of
https://github.com/okunze/Argon40-ArgonOne-Script.git
synced 2025-06-19 21:08:38 +02:00
394 lines
11 KiB
Python
394 lines
11 KiB
Python
#!/usr/bin/python3
|
|
|
|
#
|
|
# Misc methods to retrieve system information.
|
|
#
|
|
|
|
import os
|
|
import time
|
|
import socket
|
|
|
|
def argonsysinfo_listcpuusage(sleepsec = 1):
|
|
outputlist = []
|
|
curusage_a = argonsysinfo_getcpuusagesnapshot()
|
|
time.sleep(sleepsec)
|
|
curusage_b = argonsysinfo_getcpuusagesnapshot()
|
|
|
|
for cpuname in curusage_a:
|
|
if cpuname == "cpu":
|
|
continue
|
|
if curusage_a[cpuname]["total"] == curusage_b[cpuname]["total"]:
|
|
outputlist.append({"title": cpuname, "value": "0%"})
|
|
else:
|
|
total = curusage_b[cpuname]["total"]-curusage_a[cpuname]["total"]
|
|
idle = curusage_b[cpuname]["idle"]-curusage_a[cpuname]["idle"]
|
|
outputlist.append({"title": cpuname, "value": int(100*(total-idle)/(total))})
|
|
return outputlist
|
|
|
|
def argonsysinfo_getcpuusagesnapshot():
|
|
cpupercent = {}
|
|
errorflag = False
|
|
try:
|
|
cpuctr = 0
|
|
# user, nice, system, idle, iowait, irc, softirq, steal, guest, guest nice
|
|
tempfp = open("/proc/stat", "r")
|
|
alllines = tempfp.readlines()
|
|
for temp in alllines:
|
|
temp = temp.replace('\t', ' ')
|
|
temp = temp.strip()
|
|
while temp.find(" ") >= 0:
|
|
temp = temp.replace(" ", " ")
|
|
if len(temp) < 3:
|
|
cpuctr = cpuctr +1
|
|
continue
|
|
|
|
checkname = temp[0:3]
|
|
if checkname == "cpu":
|
|
infolist = temp.split(" ")
|
|
idle = 0
|
|
total = 0
|
|
colctr = 1
|
|
while colctr < len(infolist):
|
|
curval = int(infolist[colctr])
|
|
if colctr == 4 or colctr == 5:
|
|
idle = idle + curval
|
|
total = total + curval
|
|
colctr = colctr + 1
|
|
if total > 0:
|
|
cpupercent[infolist[0]] = {"total": total, "idle": idle}
|
|
cpuctr = cpuctr +1
|
|
|
|
tempfp.close()
|
|
except IOError:
|
|
errorflag = True
|
|
return cpupercent
|
|
|
|
|
|
def argonsysinfo_liststoragetotal():
|
|
outputlist = []
|
|
ramtotal = 0
|
|
errorflag = False
|
|
|
|
try:
|
|
hddctr = 0
|
|
tempfp = open("/proc/partitions", "r")
|
|
alllines = tempfp.readlines()
|
|
|
|
for temp in alllines:
|
|
temp = temp.replace('\t', ' ')
|
|
temp = temp.strip()
|
|
while temp.find(" ") >= 0:
|
|
temp = temp.replace(" ", " ")
|
|
infolist = temp.split(" ")
|
|
if len(infolist) >= 4:
|
|
# Check if header
|
|
if infolist[3] != "name":
|
|
parttype = infolist[3][0:3]
|
|
if parttype == "ram":
|
|
ramtotal = ramtotal + int(infolist[2])
|
|
elif parttype[0:2] == "sd" or parttype[0:2] == "hd":
|
|
lastchar = infolist[3][-1]
|
|
if lastchar.isdigit() == False:
|
|
outputlist.append({"title": infolist[3], "value": argonsysinfo_kbstr(int(infolist[2]))})
|
|
else:
|
|
# SD Cards
|
|
lastchar = infolist[3][-2]
|
|
if lastchar[0] != "p":
|
|
outputlist.append({"title": infolist[3], "value": argonsysinfo_kbstr(int(infolist[2]))})
|
|
|
|
tempfp.close()
|
|
#outputlist.append({"title": "ram", "value": argonsysinfo_kbstr(ramtotal)})
|
|
except IOError:
|
|
errorflag = True
|
|
return outputlist
|
|
|
|
def argonsysinfo_getram():
|
|
totalram = 0
|
|
totalfree = 0
|
|
tempfp = open("/proc/meminfo", "r")
|
|
alllines = tempfp.readlines()
|
|
|
|
for temp in alllines:
|
|
temp = temp.replace('\t', ' ')
|
|
temp = temp.strip()
|
|
while temp.find(" ") >= 0:
|
|
temp = temp.replace(" ", " ")
|
|
infolist = temp.split(" ")
|
|
if len(infolist) >= 2:
|
|
if infolist[0] == "MemTotal:":
|
|
totalram = int(infolist[1])
|
|
elif infolist[0] == "MemFree:":
|
|
totalfree = totalfree + int(infolist[1])
|
|
elif infolist[0] == "Buffers:":
|
|
totalfree = totalfree + int(infolist[1])
|
|
elif infolist[0] == "Cached:":
|
|
totalfree = totalfree + int(infolist[1])
|
|
if totalram == 0:
|
|
return "0%"
|
|
return [str(int(100*totalfree/totalram))+"%", str((totalram+512*1024)>>20)+"GB"]
|
|
|
|
def argonsysinfo_getcputemp():
|
|
try:
|
|
tempfp = open("/sys/class/thermal/thermal_zone0/temp", "r")
|
|
temp = tempfp.readline()
|
|
tempfp.close()
|
|
#cval = temp/1000
|
|
#fval = 32+9*temp/5000
|
|
return float(int(temp)/1000)
|
|
except IOError:
|
|
return 0
|
|
|
|
|
|
def argonsysinfo_getmaxhddtemp():
|
|
maxtempval = 0
|
|
try:
|
|
hddtempobj = argonsysinfo_gethddtemp()
|
|
for curdev in hddtempobj:
|
|
if hddtempobj[curdev] > maxtempval:
|
|
maxtempval = hddtempobj[curdev]
|
|
return maxtempval
|
|
except:
|
|
return maxtempval
|
|
|
|
def argonsysinfo_gethddtemp():
|
|
# May 2022: Used smartctl, hddtemp is not available on some platforms
|
|
hddtempcmd = "/usr/sbin/smartctl"
|
|
if os.path.exists(hddtempcmd) == False:
|
|
# Fallback for now
|
|
hddtempcmd = "/usr/sbin/hddtemp"
|
|
|
|
outputobj = {}
|
|
if os.path.exists(hddtempcmd):
|
|
try:
|
|
tmp = os.popen("lsblk | grep -e '0 disk' | awk '{print $1}'").read()
|
|
alllines = tmp.split("\n")
|
|
for curdev in alllines:
|
|
if curdev[0:2] == "sd" or curdev[0:2] == "hd":
|
|
tempval = argonsysinfo_getdevhddtemp(hddtempcmd,curdev)
|
|
if tempval > 0:
|
|
outputobj[curdev] = tempval
|
|
return outputobj
|
|
except:
|
|
return outputobj
|
|
return outputobj
|
|
|
|
def argonsysinfo_getdevhddtemp(hddtempcmd, curdev):
|
|
cmdstr = ""
|
|
if hddtempcmd == "/usr/sbin/hddtemp":
|
|
cmdstr = "/usr/sbin/hddtemp -n sata:/dev/"+curdev
|
|
elif hddtempcmd == "/usr/sbin/smartctl":
|
|
cmdstr = "/usr/sbin/smartctl -d sat -A /dev/"+curdev+" | grep Temperature_Celsius | awk '{print $10}'"
|
|
|
|
tempval = 0
|
|
if len(cmdstr) > 0:
|
|
try:
|
|
temperaturestr = os.popen(cmdstr+" 2>&1").read()
|
|
tempval = float(temperaturestr)
|
|
except:
|
|
tempval = -1
|
|
|
|
return tempval
|
|
|
|
def argonsysinfo_getip():
|
|
ipaddr = ""
|
|
st = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
try:
|
|
# Connect to nonexistent device
|
|
st.connect(('254.255.255.255', 1))
|
|
ipaddr = st.getsockname()[0]
|
|
except Exception:
|
|
ipaddr = 'N/A'
|
|
finally:
|
|
st.close()
|
|
return ipaddr
|
|
|
|
|
|
def argonsysinfo_getrootdev():
|
|
tmp = os.popen('mount').read()
|
|
alllines = tmp.split("\n")
|
|
|
|
for temp in alllines:
|
|
temp = temp.replace('\t', ' ')
|
|
temp = temp.strip()
|
|
while temp.find(" ") >= 0:
|
|
temp = temp.replace(" ", " ")
|
|
infolist = temp.split(" ")
|
|
if len(infolist) >= 3:
|
|
|
|
if infolist[2] == "/":
|
|
return infolist[0]
|
|
return ""
|
|
|
|
def argonsysinfo_listhddusage():
|
|
outputobj = {}
|
|
raidlist = argonsysinfo_listraid()
|
|
raiddevlist = []
|
|
raidctr = 0
|
|
while raidctr < len(raidlist['raidlist']):
|
|
raiddevlist.append(raidlist['raidlist'][raidctr]['title'])
|
|
# TODO: May need to use different method for each raid type (i.e. check raidlist['raidlist'][raidctr]['value'])
|
|
#outputobj[raidlist['raidlist'][raidctr]['title']] = {"used":int(raidlist['raidlist'][raidctr]['info']['used']), "total":int(raidlist['raidlist'][raidctr]['info']['size'])}
|
|
raidctr = raidctr + 1
|
|
|
|
rootdev = argonsysinfo_getrootdev()
|
|
|
|
tmp = os.popen('df').read()
|
|
alllines = tmp.split("\n")
|
|
|
|
for temp in alllines:
|
|
temp = temp.replace('\t', ' ')
|
|
temp = temp.strip()
|
|
while temp.find(" ") >= 0:
|
|
temp = temp.replace(" ", " ")
|
|
infolist = temp.split(" ")
|
|
if len(infolist) >= 6:
|
|
if infolist[1] == "Size":
|
|
continue
|
|
if len(infolist[0]) < 5:
|
|
continue
|
|
elif infolist[0][0:5] != "/dev/":
|
|
continue
|
|
curdev = infolist[0]
|
|
if curdev == "/dev/root" and rootdev != "":
|
|
curdev = rootdev
|
|
tmpidx = curdev.rfind("/")
|
|
if tmpidx >= 0:
|
|
curdev = curdev[tmpidx+1:]
|
|
|
|
if curdev in raidlist['hddlist']:
|
|
# Skip devices that are part of a RAID setup
|
|
continue
|
|
elif curdev in raiddevlist:
|
|
# Skip RAID ID that already have size data
|
|
# (use df information otherwise)
|
|
if curdev in outputobj:
|
|
continue
|
|
elif curdev[0:2] == "sd" or curdev[0:2] == "hd":
|
|
curdev = curdev[0:-1]
|
|
else:
|
|
curdev = curdev[0:-2]
|
|
|
|
# Aggregate values (i.e. sda1, sda2 to sda)
|
|
if curdev in outputobj:
|
|
outputobj[curdev] = {"used":outputobj[curdev]['used']+int(infolist[2]), "total":outputobj[curdev]['total']+int(infolist[1])}
|
|
else:
|
|
outputobj[curdev] = {"used":int(infolist[2]), "total":int(infolist[1])}
|
|
|
|
return outputobj
|
|
|
|
def argonsysinfo_kbstr(kbval, wholenumbers = True):
|
|
remainder = 0
|
|
suffixidx = 0
|
|
suffixlist = ["KB", "MB", "GB", "TB"]
|
|
while kbval > 1023 and suffixidx < len(suffixlist):
|
|
remainder = kbval & 1023
|
|
kbval = kbval >> 10
|
|
suffixidx = suffixidx + 1
|
|
|
|
#return str(kbval)+"."+str(remainder) + suffixlist[suffixidx]
|
|
remainderstr = ""
|
|
if kbval < 100 and wholenumbers == False:
|
|
remainder = int((remainder+50)/100)
|
|
if remainder > 0:
|
|
remainderstr = "."+str(remainder)
|
|
elif remainder >= 500:
|
|
kbval = kbval + 1
|
|
return str(kbval)+remainderstr + suffixlist[suffixidx]
|
|
|
|
def argonsysinfo_listraid():
|
|
hddlist = []
|
|
outputlist = []
|
|
# cat /proc/mdstat
|
|
# multiple mdxx from mdstat
|
|
# mdadm -D /dev/md1
|
|
|
|
ramtotal = 0
|
|
errorflag = False
|
|
try:
|
|
hddctr = 0
|
|
tempfp = open("/proc/mdstat", "r")
|
|
alllines = tempfp.readlines()
|
|
for temp in alllines:
|
|
temp = temp.replace('\t', ' ')
|
|
temp = temp.strip()
|
|
while temp.find(" ") >= 0:
|
|
temp = temp.replace(" ", " ")
|
|
infolist = temp.split(" ")
|
|
if len(infolist) >= 4:
|
|
|
|
# Check if raid info
|
|
if infolist[0] != "Personalities" and infolist[1] == ":":
|
|
devname = infolist[0]
|
|
raidtype = infolist[3]
|
|
#raidstatus = infolist[2]
|
|
hddctr = 4
|
|
while hddctr < len(infolist):
|
|
tmpdevname = infolist[hddctr]
|
|
tmpidx = tmpdevname.find("[")
|
|
if tmpidx >= 0:
|
|
tmpdevname = tmpdevname[0:tmpidx]
|
|
hddlist.append(tmpdevname)
|
|
hddctr = hddctr + 1
|
|
devdetail = argonsysinfo_getraiddetail(devname)
|
|
outputlist.append({"title": devname, "value": raidtype, "info": devdetail})
|
|
|
|
tempfp.close()
|
|
except IOError:
|
|
# No raid
|
|
errorflag = True
|
|
|
|
return {"raidlist": outputlist, "hddlist": hddlist}
|
|
|
|
|
|
def argonsysinfo_getraiddetail(devname):
|
|
state = ""
|
|
raidtype = ""
|
|
size = 0
|
|
used = 0
|
|
total = 0
|
|
working = 0
|
|
active = 0
|
|
failed = 0
|
|
spare = 0
|
|
rebuildstat = ""
|
|
tmp = os.popen('mdadm -D /dev/'+devname).read()
|
|
alllines = tmp.split("\n")
|
|
|
|
for temp in alllines:
|
|
temp = temp.replace('\t', ' ')
|
|
temp = temp.strip()
|
|
while temp.find(" ") >= 0:
|
|
temp = temp.replace(" ", " ")
|
|
infolist = temp.split(" : ")
|
|
if len(infolist) == 2:
|
|
if infolist[0].lower() == "raid level":
|
|
raidtype = infolist[1]
|
|
elif infolist[0].lower() == "array size":
|
|
tmpidx = infolist[1].find(" ")
|
|
if tmpidx > 0:
|
|
size = (infolist[1][0:tmpidx])
|
|
elif infolist[0].lower() == "used dev size":
|
|
tmpidx = infolist[1].find(" ")
|
|
if tmpidx > 0:
|
|
used = (infolist[1][0:tmpidx])
|
|
elif infolist[0].lower() == "state":
|
|
tmpidx = infolist[1].rfind(" ")
|
|
if tmpidx > 0:
|
|
state = (infolist[1][tmpidx+1:])
|
|
else:
|
|
state = infolist[1]
|
|
elif infolist[0].lower() == "total devices":
|
|
total = infolist[1]
|
|
elif infolist[0].lower() == "active devices":
|
|
active = infolist[1]
|
|
elif infolist[0].lower() == "working devices":
|
|
working = infolist[1]
|
|
elif infolist[0].lower() == "failed devices":
|
|
failed = infolist[1]
|
|
elif infolist[0].lower() == "spare devices":
|
|
spare = infolist[1]
|
|
elif infolist[0].lower() == "rebuild status":
|
|
tmpidx = infolist[1].find("%")
|
|
if tmpidx > 0:
|
|
rebuildstat = (infolist[1][0:tmpidx])+"%"
|
|
return {"state": state, "raidtype": raidtype, "size": int(size), "used": int(used), "devices": int(total), "active": int(active), "working": int(working), "failed": int(failed), "spare": int(spare), "rebuildstat": rebuildstat} |