[Résolu] Problème de limite sous RPi0 v1.3

Salut, je tente de trouver une raison d’être à mon Raspberry Pi Zero v1.3 (Sans Wireless) …

Pour la config, il est avec un adapteur RPi0 to RPi 3B, soit un PCB pour donner le « form factor »’ avec les 4 ports USB et un port réseau. J’ai ajouté un charger spécial, pris d’un ensemble démonté. Ce module d’alimentation fournis 5V à 5.0A, j’ai ajusté le voltage à 5.19V .

C’est que je dois alimenter 3 disques dur sur le USB et je veux donner un maximum de chance au RPi0.

Alors j’ai mis sur ma meilleur carte SD la dernière version de Raspbian (11) Lite 32bit et installé le minimum pour exécuter mon projet; python avec pip, samba et le pilote pour l’écran 3.5" connecté (480x320).

Voila quelques mois j’avais tenté le coup avec le X Server, et une interface graphique et j’avais eu de mauvais résultat. La partie graphique surcharge le CPU, alors j’ai pensé utiliser dernièrement par la création d’image et envoyé au FrameBuffer directement, via « FIM », mais c’est pire, le CPU restant collé à 100% et augmentant le « load » à 30~50. C’est monstrueux comme demande.

La solution actuel est alors de passer en mode texte uniquement, la je retrouve un CPU dans les 20~30% en usage moyen constant. C’est déjà plus respectable.

Mon problème étant partiellement réglé, je laisse « rouler » pour voir si tous tien la route. Oui, ça marche, l’accès au disque est un peu long mais potable, et sont but serait plus un backup qu’un NAS Multimédia. Mais après quelques heures, le script génère des erreurs et refuse de sortir le texte en console pour afficher les stats.

C’est que j’ai un écran pour voir les stats de l’appareil. Soit la charge CPU, Ram, la température du système (J’ai un module DS18B20) et l’adresse IP du réseau. J’ai aussi les stats des disques dur (espace free,use,total, % load).

Le problème est dans le temps, après quelques heures, cette affichage n’apparait plus et j’obtient un message d’erreur, indiquant avoir dépassé un limite de répétition. Actuellement j’ai relancé le projet pour générer cette erreur et vous la rapporter exactement.

Mais ce message je l’ai également eux avec l’affichage d’une image généré et envoyé via FIM. L’erreur semble venir d’une limite mémoire d’exécution. Mais pourtant je ne réutilise pas ce qui est en mémoire, généré par le script, recommençant la « Génération » à chaque cycle de 15 secondes.

Alors comment je peux éviter ça ? Je ne peut pas fermer/ouvrir le script à chaque cycle, car ^ca lui prend de 5~10s à chaque fois pour « démarrer » et générer le premier rendu.

Pour aider, voici le script;

import psutil
import platform
import os
import subprocess
import time
import datetime
from rich.console import Console
from rich.table import Table
from rich import box

DEBUG=False

def debug(txt):
   if(DEBUG is True):
       print(datetime.datetime.now().strftime("%m-%d-%y %H:%M > ") + str(txt))
       
  
## GET INFOS
def getSys():
   ## Require Temp Module Installed
   try:
       s = subprocess.check_output(["python","./temp/DS18B20/metric.py"])
       return s.decode('utf-8').replace("\n","")
   except:
       return "n/a"
   
def getCPU():
   cpupc=psutil.cpu_percent()
   return [str(platform.uname()),cpupc]
 
def getNet():
   net = ""
   if_addrs = psutil.net_if_addrs()
   for interface_name, interface_addresses in if_addrs.items():
       for address in interface_addresses:
           if(interface_name[0:3] == "eth" or interface_name[0:4] == "wlan"):
               if str(address.family) == 'AddressFamily.AF_INET':
                   if(address.address != "0.0.0.0"):
                       net = f"{address.address}"
   if(net == ""):
       net="n/a"
   net_io = psutil.net_io_counters()
   netup = getSize(net_io.bytes_sent)
   net_io = psutil.net_io_counters()
   netdown = getSize(net_io.bytes_recv)
   return [net,netup,netdown]
   
def getRAM():
   mem = psutil.virtual_memory()
   return [mem.percent,getSize(mem.total),getSize(mem.available),getSize(mem.used)]
   
def getSWAP():
   mem = psutil.swap_memory()
   return [mem.percent,getSize(mem.total),getSize(mem.free),getSize(mem.used)]
   
def getDrives():
   spaceTotal=0
   spaceFree=0
   spaceUse=0    
   out=[]
   i=1
   partitions = psutil.disk_partitions()
   for partition in partitions:
       if(partition.mountpoint == "/"):
           try:
               partition_usage = psutil.disk_usage(partition.mountpoint)
               out.append([partition.mountpoint,partition_usage.percent,getSize(partition_usage.total),getSize(partition_usage.used),getSize(partition_usage.free)])
           except PermissionError:
               continue
       elif(partition.mountpoint[0:8] == "/mnt/hdd"):
           try:
               partition_usage = psutil.disk_usage(partition.mountpoint)
               out.append([partition.mountpoint,partition_usage.percent,getSize(partition_usage.total),getSize(partition_usage.used),getSize(partition_usage.free)])
               spaceTotal=(spaceTotal+partition_usage.total)
               spaceUse=(spaceUse+partition_usage.used)
               spaceFree=(spaceFree+partition_usage.free)
           except PermissionError:
               continue
           i=(i + 1)
   if(spaceTotal != 0 and spaceUse != 0):
       spacePercent=int((spaceUse * 100) / spaceTotal)
   else:
       spacePercent=int(0)
   out.append(["Total",spacePercent,getSize(spaceTotal),getSize(spaceUse),getSize(spaceFree)])
   return out
   
def getSize(bytes, suffix="B"):
   factor = 1024
   for unit in ["", "K", "M", "G", "T", "P"]:
       if bytes < factor:
           return f"{bytes:.2f}{unit}{suffix}"
       bytes /= factor

def updates():
   global host
   debug("piNASBox start update")
   cpu=getCPU()
   ram=getRAM()
   swap=getSWAP()
   drives=getDrives()
   net=getNet()
   os.system('clear')
   table = Table(title="System",expand=True, show_header=False,title_style="bold", box=box.DOUBLE_EDGE,show_lines=True)
   rows=[["CPU LOAD",str(cpu[1])+"%","RAM LOAD",str(ram[0])+"%","SYS TEMP",str(getSys())]]
   for row in rows:
       table.add_row(*row, style='dark_orange')
   console = Console()
   console.print(table)

   table = Table(title="Network",expand=True, show_header=False,title_style="bold", box=box.DOUBLE_EDGE,show_lines=True)
   rows=[["IP ADDRESS",str(net[0])],["SPEED",str(net[1])+" UP\t|\t"+str(net[2])+" DOWN"]]
   for row in rows:
       table.add_row(*row, style='bright_blue')
   console = Console()
   console.print(table)
   
   table = Table(title="Hard Drives",expand=True, show_header=True,title_style="bold", box=box.DOUBLE_EDGE,show_lines=True)
   rows=[]
   for drive in drives:
       rows.append([str(drive[0]),str(drive[1])+"%",str(drive[3]),str(drive[4]),str(drive[2])])
   columns=["Mount","Load","Free","Used","Total"]
   for column in columns:
       table.add_column(column, justify="center", style="cyan", no_wrap=True)
   for row in rows:
       table.add_row(*row, style='bright_green')
   console = Console()
   console.print(table)

   time.sleep(15)
   updates()

debug("Loading configuration")
   
cWhite=(255,255,255)
cBlack=(0,0,0)
cRed=(255,0,0)
cGreen=(0,255,0)
cBlue=(0,0,255)
cYellow=(0,0,0)

drawFile=False
drawWidth=0
drawHeigh=0
outDraw=False
outImage=False
outFile="output.png" 
textFont="fonts/arial.ttf"

updates()

Vu le retrait du support d’image, il reste quelques artefact à ce sujet, comme des variables. Alors oui mon code a encore des « déchets » de l’ancien, mais ne sont pas utilisé, alors ne devrais pas affecter le rendu.

Le message est : RecursionError: Maximum recursion depth exceeded while calling python object

Bon, après avoir mieux pris en compte l’erreur, et modifié le code, je crois avoir résolu ce problème.

Je ne savais pas que Python avait une difficulté avec une fonction qui ce lance par elle même, je n’ai pas ce problème avec d’autre langage. En créant un While qui a la commande update() et time.sleep(15), le problème est évité.