Raketenwilli: Antwort 4: Aus meiner Bastelkiste: CPU Frequenz und Temeraturüberwachung für Raspi.

Beitrag lesen

#! /usr/bin/python3


from pathlib import Path
import math

class cpufreq:

	def __init__( self ):
		self._governor      = ''
		self._minfreq       = ''
		self._curfreq       = ''
		self._maxfreq       = ''
		self._calcstates    = ''
		self._sysruntime    = ''
		self._cpuTimefactor = 100
		self._hmFactor      = 1000000
		self._hmString      = 'GHz'
		self._tempFile      ='/sys/devices/virtual/thermal/thermal_zone0/temp'
		self._tempFaktor    = 0.001
		self._tempFormat    = '′C'
		if ( Path( '/sys/devices/system/cpu/cpu0/cpufreq/' ).is_dir() ) :
			self._path = '/sys/devices/system/cpu/cpu0/cpufreq/'
		elif ( Path( '/sys/devices/system/cpu/cpufreq/' ).is_dir() ):
			self._path = '/sys/devices/system/cpu/cpufreq/'
		self.read_from_system( );

	def read_the_line( self, fileName ):
		f = open( fileName, 'r' )
		l = f.read().strip()
		f.close()
		return l

	def human_readble( self, z ):
		z = z / self.hmFactor
		return '%0.3f %s'%( z, self._hmString )

	def Seconds2Human( self, s:int, daystring = 'd' ):
		s = int(s)
		# Days
		if ( s > 86400 ):
			d = math.floor( s / 86400 )
			s = s - d * 86400
		else:
			d = 0
		
		# Houres
		if ( s > 3600 ):
			h = math.floor( s / 3600 )
			s = s - h * 3600
		else:
			h = 0
				
		# Minutes
		if ( s > 60 ):
			m = math.floor( s / 60 )
			s = s - m * 60
		else:
			m = 0
		
		return '%d%s %02d:%02d:%02d'%( d, daystring, h, m, s )

	def read_from_system( self ):
		if ( Path( self._path + 'scaling_governor' ).exists() ):
			self._governor   =  self.read_the_line( self._path + 'scaling_governor' )
			self._minfreq    =  self.read_the_line( self._path + 'scaling_min_freq' )
			self._curfreq    =  self.read_the_line( self._path + 'scaling_cur_freq' )
			self._maxfreq    =  self.read_the_line( self._path + 'scaling_max_freq' )
		elif( Path( self._path + 'cpuinfo_min_freq' ).exists() ):
			self._governor   = false
			self._minfreq    = self.read_the_line( self._path + 'cpuinfo_min_freq' )
			self._maxfreq    = self.read_the_line( self._path + 'cpuinfo_max_freq' )

			if ( Path( self._path + 'cpuinfo_curr_freq' ).exists() ):
				self.curfreq = self.read_the_line( self._path + 'cpuinfo_cur_freq' )

			elif ( self._maxfreq == self._minfreq ):
				self._curfreq = self._minfreq

			else:
				self._curfreq = 0
		else:
			self._governor = false
			self._minfreq  = 0
			self._curfreq  = 0
			self._maxfreq  = self.read_the_line( self._path + 'cpuinfo_max_freq' )		

		if ( Path( self._path + 'stats/time_in_state' ).exists() ):
			# self._calcstates = self.read_the_line( self._path + 'stats/time_in_state' )
			self._calcstates = self.readTimestates()

		else:
			self._calcstates = false

	def human_readble ( self, z ):
		z = int(z) / self._hmFactor
		return '%0.3f %s' % ( z, self._hmString )

	def getFreq ( self, v, hm ):
		if ( hm ):
			return self.human_readble( v )
		else:
			return v

	def readTimestates( self ):
		f = open( self._path + 'stats/time_in_state' , 'r' )
		lines = f.readlines()
		f.close
		summe = 0
		arr = {}
		for line in lines:
			line = line.strip()
			if ( line ):
				f, t =  line.split(' ')
				t = math.floor( int(t) / self._cpuTimefactor )
				d = {};
				if ( t != 0 ):
					summe += t
					f = self.human_readble( f )
					d['t_abs'] = t
					d['t_hum'] = self.Seconds2Human( t )
					arr[f] = d

		self._sysruntime = summe;
				
		for f in arr.keys():
			arr[f]['t_rel'] = '%1.4f'%(round( arr[f]['t_abs'] / summe, 4 ) )
			arr[f]['t_100'] = '%5.1f%%' %( round( arr[f]['t_abs'] / summe * 100 , 1 ) )
		return arr

	def getMinFreq( self, hm = False ):
		 return self.getFreq ( self._minfreq, hm )

	def getCurFreq( self, hm = False ):
		 return self.getFreq ( self._curfreq, hm )

	def getMaxFreq( self, hm = False ):
		 return self.getFreq ( self._maxfreq, hm );

	def getSysRunTime( self, hm = False ):
		if ( hm ):
			return self.Seconds2Human( self._sysruntime );
		else:
			return self._sysruntime;		

	def getCpuTemp ( self, hm = False ):
		t = float( self.read_the_line( self._tempFile ).strip() )
		t = t * self._tempFaktor;
		if ( hm ):
			return '%4.1f%s'%(round( t, 1 ), self._tempFormat);
		else:
			return t;
	
	def getCalcstates ( self ):
		return  self._calcstates;
	
	def getGovernor ( self ):
		return self._governor;


   
    
### main ###

import os
if not os.environ.get('SHELL'):
    
    print ( 'Content-Type: text/plain; charset=utf-8' )
    print ( 'Refresh: 1' )
    print ()

cf = cpufreq()
CurFreq = cf.getCurFreq( True )

print ('Governor:              ' , cf.getGovernor() )
print ('Geringste Frequenz:    ' , cf.getMinFreq( True ) )

print ('Gegenwärtige Frequenz: ' , CurFreq , ' <' )
print ('Maximale Frequenz:     ' , cf.getMaxFreq( True ) )
print ('System läuft seit:     ' , cf.getSysRunTime( True ) )

a = cf.getCalcstates()
if ( a ):
	
	print ( 'Zeitliche Frequenznutzung:' )
	for freq in a.keys() :
		if ( freq == CurFreq ):
			LE = ' <'
		else:
			LE = ''
		print ( freq + ': ' , a[freq]['t_100'] , LE )

print ('Temperatur:' , cf.getCpuTemp( True ) )
print()

als cpufreq.py speichern, chmod 755 ...

in der ssh-shell mit watch -n1 -t cpufreq.py starten und überwachen.

Sieht dann ETWA so aus:

Governor:               ondemand
Geringste Frequenz:     1.500 GHz
Gegenwärtige Frequenz:  2.300 GHz  <
Maximale Frequenz:      2.300 GHz
System läuft seit:      1d 17:48:23
Zeitliche Frequenznutzung:
0.600 GHz:    0.0% 
0.700 GHz:    0.0% 
0.800 GHz:    0.0% 
0.900 GHz:    0.0% 
1.500 GHz:   18.3% 
1.800 GHz:    0.0% 
2.300 GHz:   81.7%  <
Temperatur: 57.5′C

Damit kannst Du nachsehen, ob der Raspi eventuell zu heiss wird und welche Frequenzen er fährt. (Meiner ist „schwer getunt“.)