'''
example name：System information display
version：v1.0
date：2020.3
Author：01Studio
Forum: forum.01studio.org
Description: Collect Raspberry Pi system information and display it on oled.
'''

#import related module
import os

#IP lib
import socket, fcntl, struct

#oled lib
from luma.core.interface.serial import i2c
from luma.core.render import canvas
from luma.oled.device import ssd1306
from time import sleep

#initialize oled
device = ssd1306(port=1, address=0x3c)

#Collect CPU temperature information, return characters                                   
def getCPUtemperature():
    res = os.popen('vcgencmd measure_temp').readline()
    return(res.replace("temp=","").replace("'C\n",""))

#Returns the percentage of CPU usage (%), character type             
def getCPUuse():
    return(str(os.popen("top -b -n1 | awk '/Cpu\(s\):/ {print $2}'").readline().strip()))

# Collect RAM information, the return unit is kB
# Index 0: Total memory
# Index 1: Memory used
# Index 2: Remaining memory                                                             
def getRAMinfo():
    p = os.popen('free')
    i = 0
    while 1:
        i = i + 1
        line = p.readline()
        if i==2:
            return(line.split()[1:4])
 
# Return the SD card capacity, the unit is GB
# Index 0: Total capacity
# Index 1: Used space
# Index 2: Remaining space
# Index 3: Usage rate (%)                                               
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])

#Get local IP address, return characters
def getIP(ifname):
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    
    #Exception handling
    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:
     
    #Collect CPU temperature information
    CPU_temp = getCPUtemperature()
    
    #Collect CPU usage
    CPU_usage = getCPUuse()
     
    #Memory information, converted to 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 card capacity information
    DISK_stats = getDiskSpace()
    DISK_total = DISK_stats[0]
    DISK_used = DISK_stats[1]
    DISK_perc = DISK_stats[3] #Use percentage
    
    #Local IP information
    IP=getIP("wlan0") 

    #oled display
    with canvas(device) as draw:
        
        draw.text((0, 0),  'CPU Temp: ' + CPU_temp + ' C', fill="white")
        draw.text((0, 10), 'CPU Used: ' + CPU_usage + ' %', fill="white")
        draw.text((0, 24), 'RAM:' + str(RAM_used) + '/' + str(RAM_total)+' MB' + ' '+RAM_perc, fill="white")
        draw.text((0, 38), 'DISK:' + str(DISK_used) + '/' + str(DISK_total) +' '+ DISK_perc, fill="white")
        draw.text((0, 52), 'IP:'+ IP, fill="white")

    sleep(0.5) #delay for a while