Python et Ethernet/UDP

Python est le langage de prédilection du Raspberry Pi

Modérateurs : Francois, Manfraid

romaxx
Messages : 78
Enregistré le : lun. 24 oct. 2016 10:59

Re: Python et Ethernet/UDP

Message par romaxx » jeu. 22 juin 2017 22:42

Bud Spencer a écrit : Tu peux nous écrire un petit bout de code d'exemple coté pi et coté arduino pour être plus explicite ?
Utilise la lib https://github.com/rblilja/DmaSerial, configure ta liaison UART pour un contrôle hardware (RTS/CTS), coté arduino rempli ton buffer avec put(), coté pi utilise l'UART en pool (utilise la lib http://www.airspayce.com/mikem/bcm2835/ car selon PI2/PI3, il faut configurer les E/S en mode ALT5 et avec cette lib c'est trivial).
Je fais le code si on me prête un arduino et une pi ;)
Désolé c'est des libs C/C++ mais bon.. python jaime pas :D
--
Adhérent à l'A.F.S.T.L

Pinhapple
Raspinaute
Messages : 125
Enregistré le : jeu. 23 févr. 2017 15:53
Localisation : Rouen

Re: Python et Ethernet/UDP

Message par Pinhapple » ven. 23 juin 2017 09:47

destroyedlolo a écrit :1t = 4,096 secondes ce qui correspond à 16384 impulsions et tu dois envoyé tes informations pour chaque tour, donc toutes les 4,096s : tu confirmes ?
Je confirme !
destroyedlolo a écrit :Si je reprend ta formule 5 + 16 384 * 3 + 16 384 * 3 = 98 309 ok mais t'où vienne les 32768 supplémentaires ? C'est pour l'enveloppe de tes données ?
C'est le nombre théorique de séparateurs nécessaires entre mes valeurs : 1 valeur de nombre d'impulsions + 16 384 valeurs de durée d'impulsion + 16 384 valeurs d'écart d'impulsion - 1 = 32 768.
destroyedlolo a écrit :Quoi qu'il en soit, 131 077 octets sur 5s, c'est vraiment pinuts en ethernet.
Ce qui m'inquiète, c'est que je n'ai pas 4 secondes pour les envoyer : le radar tourne 24/7, avec une impulsion toutes les 250 µs, donc si je veux être sûr de toutes les choper (contrainte imposée pour le projet), il faut que l'envoi de toutes les valeurs du tour écoulé se fasse entre la dernière impulsion du tour n et la première impulsion du tour n + 1.
Bud Spencer a écrit :T’es pas prêt de t’en sortir comme ça.
Je sais ! :D
Bud Spencer a écrit :Un truc qu’il faut savoir, c’est que tu ne transmets ni des chaines de caractères et encore moins des entiers. Tu ne transmets que des octets et la quantité dépend des types de départ et de l’encodage utilisé.
Oui, il ne faut pas que je me limite à mes int, mes char, etc., un octet c'est un octet.
Bud Spencer a écrit :Ce qui veut dire qu’avec ta méthode tu vas devoir envoyer les résultats d’un tour en au moins 3 séquences.
Et si je réduisais la quantité à envoyer pour augmenter la fréquence d'envoi ? Au lieu d'envoyer les valeurs d'un tour, envoyer toutes les 10, 100, 1 000 valeurs ? Reste à voir si ça peut être fait en moins de 125 µs, et si le RPi peut tout traiter (cf. un de mes sujets précédents, où le RPi "oublait" une centaine de valeurs de temps en temps).
Bud Spencer a écrit :Pour résumer, ton arduino est déjà sur les rotules à force de traitement d’interrupt. et de conversion, il n’a plus de mémoire et sa couche réseaux est totalement saturée.
Pour te répondre clairement, Non, ca ne marchera pas avec ces méthodes.
Ça a le mérite d'être clair !
Bud Spencer a écrit :Ton problème de volumétrie par tour peut tout simplement se résoudre en 32770 octets en raisonnant de la sorte :
1 word (2 octets) pour stocker la valeur d’impulsion + 16384 bytes (1 octet) pour stocker 16384 durée d’impulsion + 16384 bytes (1 octet) pour stocker 16384 durée de signaux.
De là à les envoyer en 125 µS, ce n’est pas gagné …
Merci pour le raisonnement ! Je vais essayer de fractionner un peu mes envois, en utilisant les types suggérés.
romaxx a écrit :Datasheet du W5100: Not support IP Fragmentation, ça c'est fait.

La seule solution que je vois c'est de faire de l'UART DMA, comme ça ton uC n'est pas bouffé par les interruptions de com, il se concentre sur ton acquisition de données, et ton pi vient chercher les données sur ton arduino en DMA.
J'ai jamais fait, je vais me renseigner !

Merci pour vos réponses ! ;)
  • RPi 3 + LibreELEC / RPi 3 + RetroPie / RPi B+ + Sense HAT ou Framboisedorf ou module caméra
  • Arduino Mega, Uno, Nano
  • Freescale FRDM KL25Z

destroyedlolo
Raspinaute
Messages : 1634
Enregistré le : dim. 10 mai 2015 18:44
Localisation : Dans la campagne à côté d'Annecy
Contact :

Re: Python et Ethernet/UDP

Message par destroyedlolo » ven. 23 juin 2017 10:43

Yo,

Pourquoi le
Pinhapple a écrit :il faut que l'envoi de toutes les valeurs du tour écoulé se fasse entre la dernière impulsion du tour
?

Je ferais différemment :

1/ une structure de donnée du genre

Code : Tout sélectionner

#define MAX 16384

struct data {
	unsigned short int nbre;	// nbre d'échantillons
	unsigned short int duree_montant[MAX];
	unsigned short int duree_haut[MAX];
};	
ensuite tu crée 2 buffers

Code : Tout sélectionner

struct data buf1, buf2;
Et tu bascule de l'un a l'autre par un simple modulo sur un compteur. C'est le principe du double buffering couramment utilisé en graphisme :
  1. un buffer de travail où tu stocke tes infos en cours de traitement
  2. un second avec les données du tour précédent que est "stable" pendant les 4s suivantes et que tu envoi
Ainsi, tu as tout ton temps pour tes transmissions sans perdre de donnée.

Ensuite, plutot que de le convertir en chaine, envoie tout en binaire : mais il faut t'assurer que
  • un 'unsigned short int" soit de meme taille des 2 cotés
  • comme ils sont codés sur plus d'1 octets, que le "byte ordering" soit le même des 2 cotés (LSB ou MSB mais pas un mix des 2).
La seule contrainte est d'avoir un minimum de 129K de ram dispo sur ton Arduino.

De plus, je ne connais pas comment est foutu le hat ethernet, mais s'il est bien boutu, il devrait pouvoir faire du DMA. Dans ce cas, même si ton proc est stressé par les interruptions rapide, ca n’influera pas sur les transfère qui se feront en parallèle (enfin, si les interruptions sont trop rapproché, si, mais dans ce cas, il faut que tu prennes un proc plus rapide).
Si ca ne marche pas par l'éthernet (car pas de DMA), passer par une liaison SerialDMA qui elle devrait soulager le proc (liaison plus lente que l'éthernet donc interruption de communication plus espacée.

A+
  • BananaPI : Gentoo, disque SATA de 2 To
  • Domotique : 1-wire, TéléInfo, Tablette passée sous Gentoo, ESP8266
  • Multimedia par DNLA
  • Et pleins d'idées ... et bien sûr, pas assez de temps.
Un descriptif de ma domotique 100% fait maison.

destroyedlolo
Raspinaute
Messages : 1634
Enregistré le : dim. 10 mai 2015 18:44
Localisation : Dans la campagne à côté d'Annecy
Contact :

Re: Python et Ethernet/UDP

Message par destroyedlolo » ven. 23 juin 2017 11:19

Pris d'un doute, j'ai regardé les spec de l'arduino, y'a pas 129k dispo n'est-ce pas ?

2 autres solutions :

Première : 2 buffers contiennent uniquement les données pour un cycle donc

Code : Tout sélectionner

struct data_cycle {
   unsigned short int duree_montant[MAX];
   unsigned short int duree_haut[MAX];
} cycle[2];   
sur lequel tu boucle avec un compteur.
Ca ne fait que 4 octets donc ca devrait passé en SerialDMA comme le proposait romaxx. Peut-etre aussi en ethernet si t'arrive à le configuré pour qu'il envoie un trame uniquement lors qu'elle est complete (sinon, tu auras des perfs merdiques à cause de la MTU ... elle peut etre aussi modifiée mais bon, ca peut poser des pb si les librairies sont mal foutues).
Et tu gère l'envoie des informations de tour séparément (juste un bip indiquant qu'on a changer de tour).

Seconde : en incluant un identifiant de tour dans la structure précédente qui devient

Code : Tout sélectionner

struct data_cycle {
   unsigned short int duree_montant[MAX];
   unsigned short int duree_haut[MAX];
   unsigned char idtour;
} cycle[2];   
où idtour est incrémenté à chaque fois qu'on change de tour.
5 octets du coup.

Dans les 2 cas, c'est au PI de faire la corrélation cycles/tour, soit par le bip, soit en détectant que idtour a changé.

A+
  • BananaPI : Gentoo, disque SATA de 2 To
  • Domotique : 1-wire, TéléInfo, Tablette passée sous Gentoo, ESP8266
  • Multimedia par DNLA
  • Et pleins d'idées ... et bien sûr, pas assez de temps.
Un descriptif de ma domotique 100% fait maison.

Bud Spencer
Modérateur
Messages : 1094
Enregistré le : lun. 15 août 2016 21:38

Re: Python et Ethernet/UDP

Message par Bud Spencer » ven. 23 juin 2017 13:50

Pinhapple a écrit :Et si je réduisais la quantité à envoyer pour augmenter la fréquence d'envoi ? Au lieu d'envoyer les valeurs d'un tour, envoyer toutes les 10, 100, 1 000 valeurs ? Reste à voir si ça peut être fait en moins de 125 µs, et si le RPi peut tout traiter (cf. un de mes sujets précédents, où le RPi "oublait" une centaine de valeurs de temps en temps).
Bien sûr, et tu n'as pas le choix.

Une suggestion à essayer, c'est de stocker chaque cycle sur 4 octet (2 pour le n° d'incrémentation, 1 pour la durée 1, 1 pour la durée 2) et d’envoyer sur chaque front montant. Le nombre de tours, tu t'en fous puisque de toutes façon j'imagine que tu remets le compteur du n° d'incrémentation à 0 à chaque tour. Tu peux aussi ajouter un contrôle de nouveau tour en faisant un reverse du bit le plus fort du n° d’incrémentation vu qu’en théorie tu ne dépasses pas 16384. En fonction des résultats, peut être voir pour comme tu le dis, ne faire des envois que tous les X cycles voir même utiliser 2 petits tableaux pour buffériser

Vu comme ça, ça fait beaucoup plus de données à transférer mais des petits datagrammes sorte très vite sur un socket udp ouvert. Là tu pourrais contrôler la cohérence des données de l'autre coté en voyant si les n° d'incrémentation son tous présent.

Pour faire du dma sur l'uart de l'arduino, je ne crois pas de trop. La méthode fonctionne très bien, sauf que là, ça oblige des vitesses de transfert qui ne sont d'aucune fiabilité sur un arduino (sur le pi, je n'ai jamais essayé, mais j'en doute). C'est d'ailleurs une des raisons qui m'avait fait abandonner l'arduino. En plus il faudrait encore ajouter des données pour contrôler les débuts et fins de chaque trame, voir même un checksum pour leurs validations, ce qui rajouterais encore du boulot d'identification et de contrôle à la réception. Ceci dit rien ne t'empêche d'essayer.

Apres coté PI, il faudrait savoir ce que tu veux faire de ces données à leur arrivée, mais tant que tu n'as pas validé une procédure d'envoi fiable, on s'en fout un peut ;)
Le premier ennemi de la connaissance n’est pas l’ignorance, c’est l’illusion de la connaissance (S. Hawking).

Pinhapple
Raspinaute
Messages : 125
Enregistré le : jeu. 23 févr. 2017 15:53
Localisation : Rouen

Re: Python et Ethernet/UDP

Message par Pinhapple » ven. 23 juin 2017 14:29

destroyedlolo a écrit :Pourquoi le
Pinhapple a écrit :il faut que l'envoi de toutes les valeurs du tour écoulé se fasse entre la dernière impulsion du tour
?
Parce que si l'étape création du paquet + envoi du paquet prend est bloquante, mon Arduino va louper toutes les impulsions écoulées pendant ce temps. Enfin c'est comme ça que je vois les choses, il y a peut-être quelque chose qui m'échappe !
destroyedlolo a écrit :Ainsi, tu as tout ton temps pour tes transmissions sans perdre de donnée.
Cette méthode que tu décris me plaît, mais reste ce temps d'envoi à prévoir, sachant que je ne peux pas faire de vrai threading sur Arduino comme je saurais faire en C# ou en Java.
destroyedlolo a écrit :Ensuite, plutot que de le convertir en chaine, envoie tout en binaire : mais il faut t'assurer que
  • un 'unsigned short int" soit de meme taille des 2 cotés
  • comme ils sont codés sur plus d'1 octets, que le "byte ordering" soit le même des 2 cotés (LSB ou MSB mais pas un mix des 2).
C'est le genre de trucs bon à savoir, merci pour les infos ! :D
destroyedlolo a écrit :Pris d'un doute, j'ai regardé les spec de l'arduino, y'a pas 129k dispo n'est-ce pas ?
En effet : 32 ko de mémoire flash, 2 ko de SRAM, 1 ko d'EEPROM.
Bud Spencer a écrit :En fonction des résultats, peut être voir pour comme tu le dis, ne faire des envois que tous les X cycles voir même utiliser 2 petits tableaux pour buffériser
Vous êtes plusieurs à me suggérer d'utiliser des buffers, donc je pense que ce n'est pas une mauvaise idée, mais comme je ne peux pas travailler sur les deux en même temps (remplissage de l'un pendant envoi de l'autre), qu'est-ce que ça m'apporte ? Sur une appli en multi-threading j'imagine bien un thread qui remplit le tableau, pendant qu'un autre s'occupe de l'envoi, et on inverse les threads une fois le remplissage terminé, etc., mais dans mon cas, l'envoi de mes valeurs est bloquant, donc je ne fais rien d'autre pendant ce temps-là (à part faire travailler les interruptions). Pouvez-vous m'éclairer ?
Bud Spencer a écrit :Vu comme ça, ça fait beaucoup plus de données à transférer mais des petits datagrammes sorte très vite sur un socket udp ouvert. Là tu pourrais contrôler la cohérence des données de l'autre coté en voyant si les n° d'incrémentation son tous présent.
Mon maître de stage confirme : il m'a dit de trouver un bon compromis quantité/fréquence, de manière à optimiser la vitesse d'envoi tout en gardant des performances correctes. ;)
Bud Spencer a écrit :tant que tu n'as pas validé une procédure d'envoi fiable, on s'en fout un peut ;)
Oui :lol:

Petit aparté : j'étais tellement à fond dans l'Ethernet que j'ai pas réalisé qu'il y a un lecteur de carte microSD sur le shield, dont je peux me servir pour lire et écrire dans des fichiers. A la louche comme ça, ce serait jouable d'y écrire mes valeurs dans un fichier texte dans le temps imparti ?
  • RPi 3 + LibreELEC / RPi 3 + RetroPie / RPi B+ + Sense HAT ou Framboisedorf ou module caméra
  • Arduino Mega, Uno, Nano
  • Freescale FRDM KL25Z

destroyedlolo
Raspinaute
Messages : 1634
Enregistré le : dim. 10 mai 2015 18:44
Localisation : Dans la campagne à côté d'Annecy
Contact :

Re: Python et Ethernet/UDP

Message par destroyedlolo » ven. 23 juin 2017 14:56

Pinhapple a écrit :
destroyedlolo a écrit :Ainsi, tu as tout ton temps pour tes transmissions sans perdre de donnée.
Cette méthode que tu décris me plaît, mais reste ce temps d'envoi à prévoir, sachant que je ne peux pas faire de vrai threading sur Arduino comme je saurais faire en C# ou en Java.
Pas besoin :
  • de ce que j'ai compris, tes signaux sont gérés par des interruptions donc tu peux prévoir un traitement de font dans la "boucle principale"
  • mieux, même le transfère ne doit pas d'incomber : c'est a la librairie de gérer et elle devrait le faire de manière asynchrone ; tu fournis les données, elle les envoie et te signal une fois que c'est fait.
  • si pour une raison ou une autre tu ne peux pas (librairies pourries), tu peux toujours utiliser les UART et les programmer en bas niveau. Généralement, ca se résume a placer dans un registre l'octet a transférer et a "attendre" (guillemets car évidement, on ne le fera pas par Busywait, ce qui serait idiot) l'interruption qui t'indique que l'octet a été transmis et donc que tu peux passé au suivant.
Pinhapple a écrit :Petit aparté : j'étais tellement à fond dans l'Ethernet que j'ai pas réalisé qu'il y a un lecteur de carte microSD sur le shield, dont je peux me servir pour lire et écrire dans des fichiers. A la louche comme ça, ce serait jouable d'y écrire mes valeurs dans un fichier texte dans le temps imparti ?
Déjà ... comment feras-tu pour récupérer les données ? Tu perd toute notion de temps réelle, est-ce compatible avec ton projet.
Ensuite, écrire sur une SD est relativement lent : est-ce à compatible avec tes débits ?
  • BananaPI : Gentoo, disque SATA de 2 To
  • Domotique : 1-wire, TéléInfo, Tablette passée sous Gentoo, ESP8266
  • Multimedia par DNLA
  • Et pleins d'idées ... et bien sûr, pas assez de temps.
Un descriptif de ma domotique 100% fait maison.

Bud Spencer
Modérateur
Messages : 1094
Enregistré le : lun. 15 août 2016 21:38

Re: Python et Ethernet/UDP

Message par Bud Spencer » ven. 23 juin 2017 15:37

Pinhapple a écrit :
destroyedlolo a écrit :Ensuite, plutot que de le convertir en chaine, envoie tout en binaire : mais il faut t'assurer que
  • un 'unsigned short int" soit de meme taille des 2 cotés
  • comme ils sont codés sur plus d'1 octets, que le "byte ordering" soit le même des 2 cotés (LSB ou MSB mais pas un mix des 2).
C'est le genre de trucs bon à savoir, merci pour les infos ! :D
L’ordre des bytes, tu t’en fous. A partir du moment où tu utilises une connexion réseaux. Quel que soit le système qui envois ou qui reçoit, ce sera toujours dans le bon ordre (c’est un des énormes avantages des protocoles /IP ou tout est normalisé MSB). Par contre avec une liaison série, ce n’est pas le cas.
Les types tu t’en fous aussi. Un short, un integer, un long, un word … peuvent avoir des longueurs complétement différentes suivant les systems, les langages et même les versions logicielles. A la réception, tu dois juste te soucier de choisir au plus radin des types qui soit suffisamment dimensionné et conforme à la signature des données que tu attends.
Pinhapple a écrit : Vous êtes plusieurs à me suggérer d'utiliser des buffers, donc je pense que ce n'est pas une mauvaise idée, mais comme je ne peux pas travailler sur les deux en même temps (remplissage de l'un pendant envoi de l'autre), qu'est-ce que ça m'apporte ? Sur une appli en multi-threading j'imagine bien un thread qui remplit le tableau, pendant qu'un autre s'occupe de l'envoi, et on inverse les threads une fois le remplissage terminé, etc., mais dans mon cas, l'envoi de mes valeurs est bloquant, donc je ne fais rien d'autre pendant ce temps-là (à part faire travailler les interruptions). Pouvez-vous m'éclairer ?
Tu as raison, j’avais oublié cette lacune de l’arduino. Il y a bien des solutions existantes qui ‘emule’ une forme de multi-tasking, mais de mémoire c’était très décevant et pas du tout performant. Cela avait aussi pesé sur mon choix de délaisser l’arduino pour d’autre carte. Néanmoins, ça commence à dater un peu pour moi et peut être que les générations plus récente d’Arduino sont plus évoluées de ce côté-là.
Pinhapple a écrit :
Bud Spencer a écrit :Vu comme ça, ça fait beaucoup plus de données à transférer mais des petits datagrammes sorte très vite sur un socket udp ouvert. Là tu pourrais contrôler la cohérence des données de l'autre coté en voyant si les n° d'incrémentation son tous présent.
Pinhapple a écrit : Mon maître de stage confirme ...
Si le maître, alors on est sauvé :-)))

Petit aparté : j'étais tellement à fond dans l'Ethernet que j'ai pas réalisé qu'il y a un lecteur de carte microSD sur le shield, dont je peux me servir pour lire et écrire dans des fichiers. A la louche comme ça, ce serait jouable d'y écrire mes valeurs dans un fichier texte dans le temps imparti ?
Faut essayer. Elle est connectée au cpu comment ta SD ? SPI ? 4 Bits ? Quel Format de fichier ? (je veux quand même pas lire la doc de ton arduino a ta place ;-) )
Modifié en dernier par Bud Spencer le ven. 23 juin 2017 22:34, modifié 2 fois.
Le premier ennemi de la connaissance n’est pas l’ignorance, c’est l’illusion de la connaissance (S. Hawking).

Pinhapple
Raspinaute
Messages : 125
Enregistré le : jeu. 23 févr. 2017 15:53
Localisation : Rouen

Re: Python et Ethernet/UDP

Message par Pinhapple » ven. 23 juin 2017 15:48

destroyedlolo a écrit :
  • de ce que j'ai compris, tes signaux sont gérés par des interruptions donc tu peux prévoir un traitement de font dans la "boucle principale"
  • mieux, même le transfère ne doit pas d'incomber : c'est a la librairie de gérer et elle devrait le faire de manière asynchrone ; tu fournis les données, elle les envoie et te signal une fois que c'est fait.
  • si pour une raison ou une autre tu ne peux pas (librairies pourries), tu peux toujours utiliser les UART et les programmer en bas niveau. Généralement, ca se résume a placer dans un registre l'octet a transférer et a "attendre" (guillemets car évidement, on ne le fera pas par Busywait, ce qui serait idiot) l'interruption qui t'indique que l'octet a été transmis et donc que tu peux passé au suivant.
C'est bien avec deux interruptions que je "lis" le signal, en effet.
Quand tu dis que c'est à la librairie de gérer, tu parles des biblio Ethernet/UDP de l'Arduino ? Pas une bibliothèque autre ?
destroyedlolo a écrit :Déjà ... comment feras-tu pour récupérer les données ? Tu perd toute notion de temps réelle, est-ce compatible avec ton projet.
Ensuite, écrire sur une SD est relativement lent : est-ce à compatible avec tes débits ?
En effet : après recherches, on parle de durée de l'ordre de la milliseconde pour l'écriture, même avec une "bonne" carte... :?
  • RPi 3 + LibreELEC / RPi 3 + RetroPie / RPi B+ + Sense HAT ou Framboisedorf ou module caméra
  • Arduino Mega, Uno, Nano
  • Freescale FRDM KL25Z

destroyedlolo
Raspinaute
Messages : 1634
Enregistré le : dim. 10 mai 2015 18:44
Localisation : Dans la campagne à côté d'Annecy
Contact :

Re: Python et Ethernet/UDP

Message par destroyedlolo » ven. 23 juin 2017 16:49

Bud Spencer a écrit :L’ordre de bits, tu t’en fous. A partir du moment où tu utilises une connexion réseaux. Quel que soit le système qui envois ou qui reçoit, ce sera toujours dans le bon ordre
Parfaitement FAUX.
Un simple

Code : Tout sélectionner

unsigned long int toto = 0xaabbccdd;
write(fd, &toto, sizeof(toto);
ne donnera pas le même résultat si l'un est écrit par un gros-boutiste (68000, Spark, ...) et lu sur un petit-boutiste (x86) ou l'inverse car l'octet de poids fort ne se trouve pas au même endroit.
Bud Spencer a écrit :Les types tu t’en fous aussi. Un short, un integer, un long, un word … peuvent avoir des longueurs complétement différentes suivant les systems, les langages et même les versions logicielles.
Idem : tout autant FAUX.
Seuls les int8_t, int16_t, int32_t sont normalisés (mais pas forcement supporté par les anciens compilos) : int, long int, ... dépendent de l'archi spécialement dans l'embarqué.
Pinhapple a écrit : C'est bien avec deux interruptions que je "lis" le signal, en effet.
Quand tu dis que c'est à la librairie de gérer, tu parles des biblio Ethernet/UDP de l'Arduino ? Pas une bibliothèque autre ?
Ben celle qui te sert a envoyer les données.

A+
  • BananaPI : Gentoo, disque SATA de 2 To
  • Domotique : 1-wire, TéléInfo, Tablette passée sous Gentoo, ESP8266
  • Multimedia par DNLA
  • Et pleins d'idées ... et bien sûr, pas assez de temps.
Un descriptif de ma domotique 100% fait maison.

Répondre

Retourner vers « Python »