152 lines
3.7 KiB
Python
152 lines
3.7 KiB
Python
import psutil
|
|
import sys
|
|
|
|
from gpiozero import Button
|
|
from signal import signal, SIGTERM
|
|
from subprocess import check_call
|
|
from time import sleep
|
|
from unicornhatmini import UnicornHATMini, BUTTON_A
|
|
|
|
POWER_BUTTON_HOLD_TIME_IN_SECONDS = 1
|
|
DISPLAY_UPDATE_IN_SECONDS = 2
|
|
|
|
BLACK = [0, 0, 0 ]
|
|
RED = [64, 0, 0 ]
|
|
BLUE = [0, 16, 32]
|
|
ORANGE = [64, 16, 0 ]
|
|
PINK = [64, 0, 16]
|
|
|
|
TEMP_COLOR = RED
|
|
CPU_COLOR = BLUE
|
|
NETWORK_COLOR = PINK
|
|
|
|
MIN_TEMP = 45
|
|
MAX_TEMP = 85
|
|
|
|
|
|
class SystemStatus:
|
|
|
|
def __init__(self, hat):
|
|
self.hat = hat
|
|
self.hat.set_brightness(0.1)
|
|
self.hat.set_rotation(270)
|
|
self.width, self.height = self.hat.get_shape()
|
|
|
|
self.tempStartColumn = 0
|
|
self.tempEndColumn = int(self.width / 2)
|
|
self.cpuStartColumn = int(self.width / 2)
|
|
self.cpuEndColumn = self.width - 1
|
|
self.networkStartColumn = self.width - 1
|
|
self.networkEndColumn = self.width
|
|
|
|
self.start()
|
|
|
|
def terminate(self):
|
|
self.stop()
|
|
|
|
for _ in range(3):
|
|
sleep(0.25)
|
|
self.hat.set_all(*RED)
|
|
self.hat.show()
|
|
sleep(0.25)
|
|
self.clear()
|
|
|
|
def start(self):
|
|
self.isRunning = True
|
|
self.clear()
|
|
|
|
def stop(self):
|
|
self.isRunning = False
|
|
self.clear()
|
|
|
|
def clear(self):
|
|
self.hat.set_all(*BLACK)
|
|
self.hat.show()
|
|
|
|
def display(self):
|
|
if self.isRunning:
|
|
self.displayTemp()
|
|
self.displayCpu()
|
|
self.displayNetwork()
|
|
self.hat.show()
|
|
|
|
def displayTemp(self):
|
|
self.displayField(
|
|
start=self.tempStartColumn,
|
|
end=self.tempEndColumn,
|
|
value=self.getTempValue(),
|
|
color=TEMP_COLOR
|
|
)
|
|
|
|
def displayCpu(self):
|
|
self.displayField(
|
|
start=self.cpuStartColumn,
|
|
end=self.cpuEndColumn,
|
|
value=self.getCpuValue(),
|
|
color=CPU_COLOR
|
|
)
|
|
|
|
def displayNetwork(self):
|
|
self.displayField(
|
|
start=self.networkStartColumn,
|
|
end=self.networkEndColumn,
|
|
value=self.getNetworkValue(),
|
|
color=NETWORK_COLOR
|
|
)
|
|
|
|
def displayField(self, start, end, value, color):
|
|
for x in range(start, end):
|
|
for y in range(value):
|
|
self.hat.set_pixel(x, y, *color)
|
|
for y in range(value, self.height):
|
|
self.hat.set_pixel(x, y, *BLACK)
|
|
|
|
def getTempValue(self):
|
|
temp = psutil.sensors_temperatures()['cpu_thermal'][0].current
|
|
adjusted = max(0, temp - MIN_TEMP)
|
|
percent = min(1, adjusted / (MAX_TEMP - MIN_TEMP))
|
|
|
|
return round(self.height * percent)
|
|
|
|
def getCpuValue(self):
|
|
return round(self.height * (psutil.cpu_percent() / 100))
|
|
|
|
def getNetworkValue(self):
|
|
connections = psutil.net_connections(kind='inet')
|
|
remoteConnections = [c for c in connections if c.raddr]
|
|
|
|
return min(self.height, len(remoteConnections))
|
|
|
|
|
|
def main():
|
|
systemStatus = SystemStatus(UnicornHATMini())
|
|
powerButton = Button(BUTTON_A, hold_time=POWER_BUTTON_HOLD_TIME_IN_SECONDS)
|
|
signal(SIGTERM, cleanExit(systemStatus, powerButton))
|
|
|
|
powerButton.when_held = poweroff(systemStatus)
|
|
|
|
while True:
|
|
systemStatus.display()
|
|
sleep(DISPLAY_UPDATE_IN_SECONDS)
|
|
|
|
|
|
def cleanExit(systemStatus, button):
|
|
def _cleanExit_(signum, frame):
|
|
button.close()
|
|
systemStatus.stop()
|
|
sys.exit(0)
|
|
|
|
return _cleanExit_
|
|
|
|
|
|
def poweroff(systemStatus):
|
|
def _poweroff_():
|
|
systemStatus.terminate()
|
|
check_call(['sudo', 'poweroff'])
|
|
|
|
return _poweroff_
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|