Dans mon programme, la gestion de batterie, en elle même, se résume à quelques lignes . Ce qui m'a pris plus de temps, c'est ce qu'il y a autour 😃 (la programmation , le montage sonore avec Audacity que je découvrais pour l'occasion, gimp...)
Pour les curieux qui ne veulent pas télécharger l'archive. Ci-joint la partie code (qui ne fonctionnera évidemment pas sans l'archive)
Il est composé d'un script bash et d'un script python . Les deux fonctionnent en même temps, ils sont une entité à part entière (c'est à dire qu'il faut les considérer comme un seul programme). L'appel se fait depuis le script bash.
#!/bin/bash
#Ce script nécessite d'installer le paquet acpi
etat_batterie=$(acpi -V|grep Discharging|cut -d "," -f2|sed s/%//)
if [ -z "$etat_batterie" ]; then
        exit
elif test "$etat_batterie" -lt 25;then
	if [ -f /tmp/flag ];then
		if [ "$(cat /tmp/flag)" == 1 ];then
			paplay ~/.dossier_script_batterie/t_sourd_je_fatigue.wav
			echo "2">/tmp/flag
			exit
		elif [ "$(cat /tmp/flag)" == 2 ];then
			paplay ~/.dossier_script_batterie/tu_fais_chier_je_vais_meteindre.wav
			rm /tmp/flag
			paplay coeur_decompte.wav &
			pid_paplay=$(pidof paplay)
			python3 warning.py & 
			pid_python=$(pidof -s python3)
		
			while kill -0 $pid_python 2> /dev/null; do
        			etat_batterie=$(acpi -V|grep Discharging|cut -d "," -f2|sed s/%//)
				if [ -n "$etat_batterie" ]
				then
					continue
				else 
					kill -9 $pid_paplay
					kill -9 $pid_python
					paplay ~/.dossier_script_batterie/merci.wav &
					rm /tmp/flag
					exit
				fi
			done
			kill -9 $pid_paplay 2> /dev/null
		fi
	else
		notify-send -u normal -t 50000 -i /usr/share/mate-power-manager/icons/hicolor/48x48/status/gpm-battery-020.png "Attention batterie à""$etat_batterie""%" "Branche moi stp" && paplay ~/.dossier_script_batterie/je_fatigue_recharge_moi.wav
			echo "1">/tmp/flag
			exit
                        
	fi
fi
 
#!/usr/bin/env python3
import os
from PIL import Image
import random
import time
import tkinter as tk
sens = 1
compteur = 0
CHEMIN = os.environ.get('HOME', 'username')
def fonction():
    """Déplacement du warning- Remarque la boucle sera intérompue à la 29s
depuis l'appel de mort() à partir du corps du programme."""
    global sens
    global compteur
    if sens == 1:
        compteur += 1
        if compteur == L - LOB_war:
            sens = -1
    else:
        compteur -= 1
        if compteur == 0:
            sens = 1
    can.move(warning, sens, 0)
    root.after(1, fonction)
def sortie(event):
    try:
        root.destroy()
    except:
        quit()
def mort():
    crane = dict()
    can.delete(warning)
    can.delete(mots)
    flag = False
    for i in range(1, 2):
        for x, y, a in [(1, 1, 'c1'), (710, 600, 'c2'), (1420, 1, 'c3'),
                        (710, 1, 'c4'), (1, 600, 'c5'), (1420, 600, 'c6')]:
            if flag:
                can.delete(crane[a])
            root.update()
            crane[a] = can.create_image(int(x*COEFF_L), int(y*COEFF_H),
                                        anchor='nw', image=photocrane)
            root.update()
            time.sleep(1/2)
        flag = True
# étape2
    for y in range(int(600*COEFF_H), 1, -2):
        can.move(crane['c2'], 0, -2)
        can.move(crane['c5'], 0, -2)
        can.move(crane['c6'], 0, -2)
        root.update()
    for i in ['c2', 'c5', 'c6']:
        can.delete(crane[i])
    root.update()
    for x in range(int(1*COEFF_L), int(710*COEFF_L), 2):
        can.move(crane['c1'], 2, 0)
        root.update()
    for x in range(int(1420*COEFF_L), int(710*COEFF_L), -2):
        can.move(crane['c3'], -2, 0)
        root.update()
    can.delete(crane['c1'])
    can.delete(crane['c3'])
# bouche qui bouge.
    for i in range(10):
        can.delete(crane['c4'])
        crane['c4_2'] = can.create_image(int(710*COEFF_L), int(1*COEFF_H),
                                         anchor='nw', image=photocrane2)
        root.update()
        time.sleep(1/10)
        can.delete(crane['c4_2'])
        crane['c4_3'] = can.create_image(int(710*COEFF_L), int(1*COEFF_H),
                                         anchor='nw', image=photocrane3)
        root.update()
        time.sleep(1/10)
        can.delete(crane['c4_3'])
        crane['c4'] = can.create_image(int(710*COEFF_L), int(1*COEFF_H),
                                       anchor='nw', image=photocrane)
        root.update()
    can.delete(crane['c4'])
# taille crane(500*480) qui diminue 'sur place' jusqu'à 250*240p en cinq images
    ecart = 0  # resize de 10 pixels
    img = Image.open(CHEMIN +
                     "/.dossier_script_batterie/crane.png", 'r')
    HOB, LOB = img.size
    for i in range(0, 25):
        ecart += 10
        image = img.resize((int((HOB-ecart)*COEFF_H),
                            int((LOB-ecart)*COEFF_H)))
        image.save('/tmp/craneresize.png')
        photocranebis = tk.PhotoImage(file="/tmp/craneresize.png")
        cranediminue = can.create_image(int((710+ecart/2)*COEFF_L),
                                        int((1+ecart/2)*COEFF_H),
                                        anchor='nw', image=photocranebis)
        root.update()
        if i == 24:
            can.delete(cranediminue)
# le crane tourne sur place et s'accélère
# à noter que je repars sur une nouvelle image de
# 300*290 dont le masque est suffisant(+50p)pour permettre la rotation
# sans tronquer l'image (qui elle reste à 250*240)
    img = Image.open('/tmp/crane_masque_grandi.png', "r")
    HOB, LOB = img.size
    cranetourne = dict()
    phototourne = dict()
    acceleration = [100, 50, 25, 10, 5]
    for angle in range(0, 361, 30):
        phototourne[angle] = tk.PhotoImage(
            file="/tmp/crane_tourne"+str(angle)+".png")
    while acceleration:
        accelere = acceleration.pop()
        for angle in range(0, 361, 30):
            cranetourne[angle] = can.create_image(
                int((710+(ecart/2)-25)*COEFF_L),
                int((y+(ecart/2)-25)*COEFF_H),
                anchor='nw', image=phototourne[angle])
            time.sleep(1/accelere)
            root.update()
            can.delete(cranetourne[angle])
# sénario cranes qui tournent et partent au hazard d'une direction
# puis rebondi sur limite du canevas
    boucle = 5
    angle = 0
    x = 0
    y = 0
    sensx = 1
    sensy = 1
    pos = [1, -1]
    randomy = pos[random.randint(0, 1)] * 4
    randomx = pos[random.randint(0, 1)] * 4
    while True:
        y += randomy * sensx
        x += randomx * sensy
        if angle == 390:
            angle = 0
        cranetourne[angle] = can.create_image(int((710+x+ecart/2-25)*COEFF_L),
                                              int((y+ecart/2-25)*COEFF_H),
                                              anchor='nw',
                                              image=phototourne[angle])
        root.update()
        time.sleep(1/100)
        can.delete(cranetourne[angle])
        angle += 30
        time.sleep(1/100)
        if (y+ecart/2-25) * COEFF_H > (1080-HOB) * COEFF_H:
            sensx *= -1
            boucle -= 1
            if boucle == 0:
                root.destroy()
                break
        elif(y+ecart/2-25) * COEFF_H < 1:
            sensx *= -1
            boucle -= 1
            if boucle == 0:
                root.destroy()
                break
        elif(710+x+ecart/2-25) * COEFF_L > (1920-LOB) * COEFF_L:
            sensy *= -1
            boucle -= 1
            if boucle == 0:
                break
                root.destroy()
        elif (710+x+ecart/2-25)*COEFF_L < 0:
            sensy *= -1
            boucle -= 1
            if boucle == 0:
                root.destroy()
                break
            
def apropos(event):
    global imapropos
    photoapropos = tk.PhotoImage(file="/tmp/apropos.png")
    imapropos = can.create_image(int(960*COEFF_L), int(520*COEFF_H)
                                 ,
                                 anchor='center', image=photoapropos, tag="quitter")
    can.tag_bind("quitter", "<Button-1>", quitteapropos)
    
    root.update()
    
def quitteapropos(event):
    can.delete(imapropos)
  
    
# Début du programme
root = tk.Tk()
# soit L ,H, largeur et hauteur pixel de la machine hôte
L = root.winfo_screenwidth()
H = root.winfo_screenheight()
COEFF_L = L / 1920
COEFF_H = H / 1080
# Chargement photos ---->resize
img = Image.open(CHEMIN +
                 "/.dossier_script_batterie/warningbis.png",
                 'r')
HOB, LOB = img.size
image = img.resize((int(HOB*COEFF_L), int(LOB*COEFF_L)))
image.save('/tmp/warning.png')
img = Image.open(CHEMIN+"/.dossier_script_batterie/crane.png", 'r')
HOB, LOB = img.size
image = img.resize((int(HOB*COEFF_L), int(LOB*COEFF_L)))
image.save('/tmp/crane.png')
img = Image.open(CHEMIN+"/.dossier_script_batterie/crane2.png", 'r')
HOB, LOB = img.size
image = img.resize((int(HOB*COEFF_L), int(LOB*COEFF_L)))
image.save('/tmp/crane2.png')
img = Image.open(CHEMIN+"/.dossier_script_batterie/crane3.png", 'r')
HOB, LOB = img.size
image = img.resize((int(HOB*COEFF_L), int(LOB*COEFF_L)))
image.save('/tmp/crane3.png')
img = Image.open(CHEMIN +
                 "/.dossier_script_batterie/crane_masque_grandi.png"
                 , 'r')
HOB, LOB = img.size
image = img.resize((int(HOB*COEFF_L), int(LOB*COEFF_L)))
image.save('/tmp/crane_masque_grandi.png')
img = Image.open(CHEMIN +"/.dossier_script_batterie/apropos.png"
                 , 'r')
HOB, LOB = img.size
image = img.resize((int(HOB*COEFF_L), int(LOB*COEFF_L)))
image.save('/tmp/apropos.png')
# Création têtes qui tournent
img = Image.open('/tmp/crane_masque_grandi.png')
HOB, LOB = img.size
for angle in range(0, 361, 30):
        crane = img.rotate(angle)
        crane.save("/tmp/crane_tourne"+str(angle)+".png")
# #########
root.attributes('-fullscreen', 1)
can = tk.Canvas(root, width=L, height=int(1080/COEFF_L),
                background='black')
can.pack()
bouton = tk.PhotoImage (file=CHEMIN + "/.dossier_script_batterie/bouton.png")
can.create_image(int(1920*COEFF_L), 1, anchor='ne', image=bouton, tag="choisir")
can.tag_bind("choisir", "<Button-1>", apropos)
photo = tk.PhotoImage(file="/tmp/warning.png")
photocrane = tk.PhotoImage(file="/tmp/crane.png")
photocrane2 = tk.PhotoImage(file="/tmp/crane2.png")
photocrane3 = tk.PhotoImage(file="/tmp/crane3.png")
img = Image.open("/tmp/warning.png")
LOB_war = img.size[1]
warning = can.create_image(1, int(540*COEFF_H), anchor='w', image=photo)
mots = can.create_text(int(960*COEFF_L), int(1000*COEFF_H),
                       text="Appuie sur une touche pour quitter",
                       font=("Courrier", int(60*L/1920), 'bold'),
                       anchor='center', fill="red")
root.after(28500, mort)
root.bind('<KeyPress>', sortie)
fonction()
root.mainloop()