giampaolo / psutil

Cross-platform lib for process and system monitoring in Python
BSD 3-Clause "New" or "Revised" License
10.28k stars 1.39k forks source link

[Raspberry Pi OS/Debian] `psutil.cpu_percent()` shows wrong percentage, sort of #2030

Closed Crilum closed 2 years ago

Crilum commented 2 years ago

Summary

Description

I'm editing a script that displays CPU Temp and Time on an LCD screen, and instead of having CPU Temp and Time, I wanted to have CPU usage in percent, and the CPU frequency, so I made a function for both:

def get_cpu_percent(): # get CPU usage
    cpuper = psutil.cpu_percent(interval=0.5)
    return '{:.2f}'.format( float(cpuper)/1000 ) + ' %'
def get_cpu_frequency():
    return str(psutil.cpu_freq().current)

and called it in a loop:

def loop():
    mcp.output(3,1)     # turn on LCD backlight
    lcd.begin(16,2)     # set number of LCD lines and columns
    while(True):         
        #lcd.clear()
        lcd.setCursor(0,0)  # set cursor position
        #lcd.message( 'CPU Temp: ' + get_cpu_temp()+'\n' )# display CPU temperature
        lcd.message( 'CPU %: ' + get_cpu_percent() + '\n' )
        lcd.message( 'CPU MHz: ' + get_cpu_frequency() )
        #lcd.message( get_time_now() )   # display the time
        sleep(1)

and ran the loop.

And it worked, but the get_cpu_percent() function shows CPU %: 0.03on the LCD when called in the loop. The 3 is an echo of every 10%, so if the CPU were running at 50%, the LCD would show CPU %: 0.05, and if the CPU were running at 100%, the LCD would show CPU %: 0.10 (theoretically, I haven't used the CPU at 100% to test..), and so on and so forth.. The frequency function worked fine.

If this is a user error, sorry.. I'm new to python..

This is the whole script:

#!/usr/bin/env python3
from PCF8574 import PCF8574_GPIO
from Adafruit_LCD1602 import Adafruit_CharLCD

from time import sleep, strftime
from datetime import datetime
import psutil

def get_cpu_temp():     # get CPU temperature and store it into file "/sys/class/thermal/thermal_zone0/temp"
    tmp = open('/sys/class/thermal/thermal_zone0/temp')
    cpu = tmp.read()
    tmp.close()
    return '{:.2f}'.format( float(cpu)/1000 ) + 'C'

def get_cpu_percent(): # get CPU usage
    cpuper = psutil.cpu_percent(interval=0.5)
    return '{:.2f}'.format( float(cpuper)/1000 ) + ' %'
    print(cpuper())

def get_cpu_frequency():
    return str(psutil.cpu_freq().current)

def get_time_now():     # get system time
    return datetime.now().strftime('Time: %H:%M:%S')

def loop():
    mcp.output(3,1)     # turn on LCD backlight
    lcd.begin(16,2)     # set number of LCD lines and columns
    while(True):         
        #lcd.clear()
        lcd.setCursor(0,0)  # set cursor position
        #lcd.message( 'CPU Temp: ' + get_cpu_temp()+'\n' )# display CPU temperature
        lcd.message( 'CPU %: ' + get_cpu_percent() + '\n' )
        lcd.message( 'CPU MHz: ' + get_cpu_frequency() )
        #lcd.message( get_time_now() )   # display the time
        sleep(1)
def destroy():
    print('Aborting!')
    lcd.clear()

PCF8574_address = 0x27  # I2C address of the PCF8574 chip.
PCF8574A_address = 0x3F  # I2C address of the PCF8574A chip.
# Create PCF8574 GPIO adapter.
try:
    mcp = PCF8574_GPIO(PCF8574_address)
except:
    try:
        mcp = PCF8574_GPIO(PCF8574A_address)
    except:
        print ('I2C Address Error !')
        exit(1)
# Create LCD, passing in MCP GPIO adapter.
lcd = Adafruit_CharLCD(pin_rs=0, pin_e=2, pins_db=[4,5,6,7], GPIO=mcp)

if __name__ == '__main__':
    print ('Program is starting ... ')
    try:
        loop()
    except KeyboardInterrupt:
        destroy()
n-ext commented 2 years ago

Seems like your error. Just remove /1000 from get_cpu_percent().

def get_cpu_percent(): # get CPU usage
    cpuper = psutil.cpu_percent(interval=0.5)  # <-- It returns value in %, so for 50% it returns 50.0 etc
    return '{:.2f}'.format( float(cpuper)/1000 ) + ' %'  # <-- Here you are dividing by 1000, so your 50.0 becomes 0.05
Crilum commented 2 years ago

Ahh, thanks!