Bibliothèque phue.py

Bonjour à toutes et à tous.
Cela fait un an que j’ai entièrement domotisé ma maison, et tout est contrôlé par un programme que j’ai écrit. Dans celui-ci j’utilise la bibliothèque phue.py pour contrôler mes lampes Phillips HUE. Jusque là tout fonctionne bien, mais de temps en temps cette bibliothèque me sort l’erreur : socket.timeout: timed out. Je sais à quoi cela est dû, c’est le pont Phillips qui est un peu long à répondre, mais je ne sais pas comment faire pour l’éviter. Ça ne ce produit pas tout le temps, c’est aléatoire. Quelqu’un aurait-il une idée?

Voici la partie du code ou cela se produit:

def test_on_off():

       global arret

       while True:
    
            x = len(nom_lampe2)
            for z in range(x):
        
                if arret==2:
            
                    time.sleep(arret)
                    arret = 0
                    
                try:
                    
                    if b.get_light(nom_lampe2[z], 'on')==True:

                        self.image = QPixmap("icons/allume.png")
                        elem[z]["self.pushButton"].setText("OFF")
                        elem[z]["self.label_5"].setPixmap(self.image)
                    
                        if smart in nom_lampe2[z]:
    
                            pass

                        else:

                            bright = b.get_light(nom_lampe2[z], 'bri')
                            bright = bright/2.54
                            elem[z]["self.Slider"].setValue(bright)
            
                    elif b.get_light(nom_lampe2[z], 'on')==False:

                        self.image = QPixmap("icons/eteind.png")
                        elem[z]["self.pushButton"].setText("ON")
                        elem[z]["self.label_5"].setPixmap(self.image)
                    
                        if smart in nom_lampe2[z]:
    
                            pass

                        else:
                        
                            elem[z]["self.Slider"].setValue(0)

                except:
                    
                    test_on_off()
                     
            time.sleep(1)

Je n’ai pas de réponse car le problème n’est pas la…

Ton code représente un changement dans un UI. De ce que je vois aucun code fait référence a l’usage de socket ou autres. La seul chose que je vois qui serait en lien est peut être le b.get_light.

Ton erreur « socket.timeout: timed out » fait référence a un lien réseau qui dépasse un délais, soit un appel vers la lumière, mais cette dernière prend trop de temps a répondre. Dans le code que tu fournis, il y a rien de ça.

Alors ton problème vient d’ailleur.

Autre chose, ajouter un appel a la propre commande dans un except c’est très dangereux, c’est un « Evil Loop ». Car si une erreur ce produit et que le code retente de faire la commande, tu risque de refaire la même erreur et créer un cercle sans fin. Pense plutot à faire autrement, comme un avertissement au lieu de rester dans la commande.

Merci pour ta réponse, il est vrai que l’erreur ne viens pas de ce bout de code, mais il fait appel à la biblio phue.py.
Je sais que j’ai fait un Evil Loop, mais je ne sais pas faire autrement. Après excep, si je met pass au lieu de
test_on_off(), est que ce serai mieux? Ce code est dans un Thread, donc il ne faut surtout pas qu’il en sorte.

C’est que si dans la première lancé de la fonction il bug, il a forte chance que dans la deuxième demande il produise la même erreur. C’est mieux de simplement faire un print("Error: Can't do on/off") pour laisser une trace du bug, mais il va continuer et ne pas faire planter tout le script. Dans ce contexte, le script va continuer ce qu’il doit faire et non être pris dans le loop possible si le bug est persistent.

Pour ton erreur de socket, il faudra alors l’ensemble du message d’erreur et les codes qui sont affecté, alors commence par poster le message d’erreur au complet et ont verra ce qu’ont doit régler par la suite.

Bonjour,
D’accord, je pensai que ce serait plus compliqué pour éviter un plantage du programme. Après Except j’ai mis pass, mais il est vrai qu’un print serai mieux au moins pour avoir une trace.
voici le message d’erreur:

GET Request to 192.168.1.30/api/xxxxxxxxxxxxxxxxxxxxxxxxxxxxx/lights/ timed out.
Traceback (most recent call last):
File « /home/pi/.local/lib/python3.7/site-packages/phue.py », line 650, in request
connection.request(mode, address)
File « /usr/lib/python3.7/http/client.py », line 1244, in request
self._send_request(method, url, body, headers, encode_chunked)
File « /usr/lib/python3.7/http/client.py », line 1290, in _send_request
self.endheaders(body, encode_chunked=encode_chunked)
File « /usr/lib/python3.7/http/client.py », line 1239, in endheaders
self._send_output(message_body, encode_chunked=encode_chunked)
File « /usr/lib/python3.7/http/client.py », line 1026, in _send_output
self.send(msg)
File « /usr/lib/python3.7/http/client.py », line 966, in send
self.connect()
File « /usr/lib/python3.7/http/client.py », line 938, in connect
(self.host,self.port), self.timeout, self.source_address)
File « /usr/lib/python3.7/socket.py », line 727, in create_connection
raise err
File « /usr/lib/python3.7/socket.py », line 716, in create_connection
sock.connect(sa)
socket.timeout: timed out
Exception in thread Thread-2:
Traceback (most recent call last):
File « /home/pi/.local/lib/python3.7/site-packages/phue.py », line 650, in request
connection.request(mode, address)
File « /usr/lib/python3.7/http/client.py », line 1244, in request
self._send_request(method, url, body, headers, encode_chunked)
File « /usr/lib/python3.7/http/client.py », line 1290, in _send_request
self.endheaders(body, encode_chunked=encode_chunked)
File « /usr/lib/python3.7/http/client.py », line 1239, in endheaders
self._send_output(message_body, encode_chunked=encode_chunked)
File « /usr/lib/python3.7/http/client.py », line 1026, in _send_output
self.send(msg)
File « /usr/lib/python3.7/http/client.py », line 966, in send
self.connect()
File « /usr/lib/python3.7/http/client.py », line 938, in connect
(self.host,self.port), self.timeout, self.source_address)
File « /usr/lib/python3.7/socket.py », line 727, in create_connection
raise err
File « /usr/lib/python3.7/socket.py », line 716, in create_connection
sock.connect(sa)
socket.timeout: timed out

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File « /home/pi/Programmation/MyDomotic_V3_1/MyDomotic_V3_1.py », line 557, in test_on_off
if b.get_light(nom_lampe2[z], ‹ on ›)==True:
File « /home/pi/.local/lib/python3.7/site-packages/phue.py », line 832, in get_light
light_id = self.get_light_id_by_name(light_id)
File « /home/pi/.local/lib/python3.7/site-packages/phue.py », line 755, in get_light_id_by_name
lights = self.get_light()
File « /home/pi/.local/lib/python3.7/site-packages/phue.py », line 834, in get_light
return self.request(‹ GET ›, ‹ /api/ › + self.username + ‹ /lights/ ›)
File « /home/pi/.local/lib/python3.7/site-packages/phue.py », line 660, in request
raise PhueRequestTimeout(None, error)
phue.PhueRequestTimeout: (None, ‹ GET Request to 192.168.1.30/api/VLMx100vYzGGlvoWssGs4Fsgncon4V0Zo3fsu71s/lights/ timed out. ›)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File « /usr/lib/python3.7/threading.py », line 917, in _bootstrap_inner
self.run()
File « /usr/lib/python3.7/threading.py », line 865, in run
self._target(*self._args, **self._kwargs)
File « /home/pi/Programmation/MyDomotic_V3_1/MyDomotic_V3_1.py », line 587, in test_on_off
except socket.timeout:
NameError: name ‹ socket › is not defined

A savoir qu’avec:

except socket.timeout:
    pass

Cela semble fonctionner sans plantage.

Tu as deux erreurs;

Celui que j’ai repéré facilement est ;

Ici le module « socket » n’est pas chargé dans le fichier ; /home/pi/Programmation/MyDomotic_V3_1/MyDomotic_V3_1.py

Le problème se résous par l’ajout dans le haut du script import socket .


Le secon est plus complexe, il est dans la librairie de PHUE, alors l’idéal est de ne pas modifier le source de PHUE et quand tu appel l’une de ces commandes, de le mettre dans un « try », si il y a erreur, retourne une valeur « neutre » ou « safe ». Je ne sais pas comment la réponse est retourné depuis le « GET…/API/… » mais tu peux avec le Try si il y a erreur, retourner une valeur pour traiter cette erreur plus loin, pour par exemple attendre et tenter un « retry » ou retourner une valeur « neutre », tout dépend de ton code.

Si ton raspberry est connecté via le Wifi, le timeout peut être causé par un signal faible ou une interférence, changer de canal du routeur Wifi peut aider a éviter cette situation.

Si ton installation est câblé, alors l’appareil distant est lent a répondre, si tu ne peut pas améliorer la rapidité il faudra te contenter de gérer l’erreur.


Si le contexte le demande, tu peux ajouter un code pour faire un auto-retry, je te suggère de faire 3 ou 5 tentative avant de retourner une erreur. Il faudra incrémenter une varaible pour savoir combien de « try » ont été fait (qui est remis à zéro une fois la demande complété ou lorsque l’appel s’effectue sur un autre accès). Comme sa tu peux gérer l’erreur en affichant a la limite d’essai un message d’erreur avisant qu’après X tentatives, la communication n’a pas été complété.

Plusieurs choses peut créer des timeout, soit le délais est trop cours, soit la communication est mauvaise. soit un problème physique (un câble peut subir des interférence électrique, par l’alimentation dans les murs par exemple).

Il n’y as pas de solution définitive pour les timeout, faut plus les gérer adéquatement selon le code et le besoin.