'''
实验名称：系统信息显示
版本： v1.0
日期： 2021.7
作者： 01Studio
说明：通过编程采集Jetson Nano系统信息，并在oled显示。
社区：www.01studio.org
'''

#导入相关库
import os,board,busio

#IP lib
import socket, fcntl, struct

#oled lib
import adafruit_ssd1306

from time import sleep

#构建I2C对象
i2c = busio.I2C(board.SCL1, board.SDA1)

#构建oled对象,01Studio配套的OLED地址为0x3C
display = adafruit_ssd1306.SSD1306_I2C(128, 64, i2c, addr=0x3C)

def getCPUtemperature():
    res = os.popen('cat /sys/class/thermal/thermal_zone0/temp').readline()
    return '%.1f'%(int(res)/1000)

#返回CPU使用率百分比（%），字符类型                             
def getCPUuse():
    return(str(os.popen("top -b -n1 | awk '/Cpu\(s\):/ {print $2}'").readline().strip()))

# 采集RAM信息，返回单位是kB                                      
# Index 0: 总内存                                                               
# Index 1: 已使用内存                                                               
# Index 2: 剩余内存                                                               
def getRAMinfo():
    p = os.popen('free')
    i = 0
    while 1:
        i = i + 1
        line = p.readline()
        if i==2:
            return(line.split()[1:4])
 
# 返回SD卡容量大小，单位是GB                    
# Index 0: 总容量                                                        
# Index 1: 已用空间                                                        
# Index 2: 剩余空间                                                    
# Index 3: 使用率（%）                                                 
def getDiskSpace():
    p = os.popen("df -h /")
    i = 0
    while 1:
        i = i +1
        line = p.readline()
        if i==2:
            return(line.split()[1:5])

#获取本地IP地址，返回字符
def getIP(ifname):
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    
    #异常处理
    try:
        return socket.inet_ntoa(fcntl.ioctl( 
            s.fileno(), 
            0x8915,  # SIOCGIFADDR 
            struct.pack('256s', ifname[:15].encode('utf-8')) 
           )[20:24])
    
    except OSError:
        return('0.0.0.0')

while True:
    
    #采集CPU温度信息
    CPU_temp = getCPUtemperature()
    print(type(CPU_temp))
    print(CPU_temp)
    
    #采集CPU使用率
    CPU_usage = getCPUuse()
     
    #内存信息，转化成MB
    RAM_stats = getRAMinfo()
    RAM_total = int(int(RAM_stats[0]) / 1000)
    RAM_used = int(int(RAM_stats[1]) / 1000)
    RAM_free = int(int(RAM_stats[2]) / 1000)
    RAM_perc = str(round((RAM_used/RAM_total*100),1))+'%'
     
    #sd卡容量信息
    DISK_stats = getDiskSpace()
    DISK_total = DISK_stats[0]
    DISK_used = DISK_stats[1]
    DISK_perc = DISK_stats[3] #使用百分比
    
    #无线网络IP信息
    Wlan0_IP=getIP("wlan0")
    #print(Wlan0_IP)
    
    #以太网IP信息
    Eth0_IP=getIP("end1")
    #print(Eth0_IP)

    #清空显示屏
    display.fill(0)
    
    #oled显示
    display.text('CPU Temp: ' + CPU_temp + ' C', 0, 0, 1,font_name='./font5x8.bin')
    display.text('CPU Used: ' + CPU_usage + ' %', 0, 12, 1,font_name='./font5x8.bin')
    display.text('RAM:' + str(RAM_used) + '/' + str(RAM_total)+'MB' + ' '+RAM_perc, 0, 24, 1,font_name='./font5x8.bin')
    display.text('DISK:' + str(DISK_used) + '/' + str(DISK_total) +' '+ DISK_perc, 0, 38, 1,font_name='./font5x8.bin')
    
    #IP显示
    if Wlan0_IP != '0.0.0.0' :
        
        display.text('wlan0:'+ Wlan0_IP, 0, 50, 1,font_name='./font5x8.bin')
        
    elif Eth0_IP != '0.0.0.0' :
        display.text('eth0:'+ Eth0_IP, 0, 50, 1,font_name='./font5x8.bin')
    
    else:
        display.text('IP:0.0.0.0', 0, 50, 1,font_name='./font5x8.bin')
            
    display.show()

    sleep(1) #延时，数据更新间隔