salut a vous ,
donc j'ai recommencer a zero , j'ai recreer un git :
https://github.com/ludoiphone/gainable-en-fabrication
je vais me pencher sur les temporisations .
Version imprimable
salut a vous ,
donc j'ai recommencer a zero , j'ai recreer un git :
https://github.com/ludoiphone/gainable-en-fabrication
je vais me pencher sur les temporisations .
Attention :
Code:
1
2
3
4
5
6 class Chauffage { public: void chauffage(); };
Code:
1
2
3
4
5
6 #include "chauffage.h" void Chauffage::chauffage() { cout << "fabrication du chauffage" << endl << endl; }
S'il s'agit ici d'un constructeur, celui-ci doit porter exactement le nom de la classe… en respectant la casse ! Il faut mettre une majuscule à la lettre C du nom de la classe et celui de la fonction-membre, ou ne pas en mettre du tout.
Et en conséquence, comme un constructeur est forcément void par nature, cela est implicite. Il faudra donc retirer la qualification de type aussi bien dans la déclaration de la classe qu'à la définition de la fonction.
Pourquoi "tempExtLue, tempUnitExtLue, tempEchExtLue, tempUnitIntLue, tempEchIntLue" comme membre de la classe "DS18B20".
Idem pour "buffer" ou "end".
Pourquoi ce mélange de fichier en ".h" et en ".hpp".
La fonction de chaque classe me semble pas claire, surtout la classe "Modes".
Pourquoi l'objet "modes" ne peut-il pas être autonome et aller lui-même demander la température ???Citation:
Code:modes.SetTemperatureExt(temperatureExt.GetTempExt());
Pourquoi faire une boucle active "à fond les ballons" avec ce ridicule "sleep(1)" ?Code:
1
2
3
4
5
6
7
8
9 DS18B20 temperatureExt; Modes modes(temperatureExt); ... if (time(nullptr) - chrono >= deltaT) { modes.productions(); chrono = time(nullptr); }
Vous n'avez toujours pas appliqué nos "conseilles" de codage.
La temporisation semble centrale dans votre projet mais je ne vois rien de concret sur le sujet dans vote prototype.
C'est maintenant que vous devez évaluer les alternatives d'implémentation pour connaitre si elles correspondent à vos besoins.
std::async ne convient pas ? https://en.cppreference.com/w/cpp/thread/async.html
Il semble toujours que la distinction classe/objet ne soit pas claire, cf. "const int thermostats = 17;"
pour le chauffage je mettais tromper ; j'ai rectifier dans github.
c'etait bien une fonction mais mal ecrite desolé.
Pourquoi "tempExtLue, tempUnitExtLue, tempEchExtLue, tempUnitIntLue, tempEchIntLue" comme membre de la classe "DS18B20".
car j'ai 5 sondes dans un fichier et elles ont leur propre fichier (adresse Ds18b20).
Code:
1
2
3 /sys/bus/w1/devices/28-3ce1e3804835/temperature = sonde Ext /sys/bus/w1/devices/28-3ce1e3809744/temperature = sonde UnitExt ...
pour le hpp, je sais pas trop car c'est une class que l'on ma fourni . je pense que c'est pour stipuler que c'est du c++, h++.
pour modes.SetTemperatureExt(temperatureExt.GetTempExt()); je ne savait pas trop comment faire ; je suis debutant :oops:
en gros l'ideal en que je doit mettre DS18B20 dans Modes ??
le sleep me sert a voir ce qu'il ce passe , si non cela vas trop vite , il sera retirer a la fin .
les temporisations , oui sont tres important car elle servent pour actionner les diferents relais et controler les temperatures en fonction de l'etat ou le programme vas ce trouver a un temp donner .
et apres pour mettre a jour les temperatures sur l'ecran . mais pour l'instant avec vos conseilles est de construire le code metier et apres la partie ecran.
j'avais un peux compris les thread sur Qt ; mais en c++ ??
la class sert a creer un objet .
et j'avoue que ce n'ai pas si evident que cela !
j'essais de faire de mon mieux pour tous comprendre du au de mes 45 ans en sachant que je travaille sur ce projet que qu'elle que heure par jours , avec 6 gamins en plus a la maison
je vous dit pas que je suis toujours soliciter (crit , bagarre, pleure) mais bon !
merci a vous de donner votre precieux temps .
Citation:
pour le chauffage je mettais tromper ; j'ai rectifier dans github.
Je ne vois pas comment correctement utiliser cette classe. Je trouve qu'elle manque d'affordance (https://fr.wikipedia.org/wiki/Affordance).Citation:
Code:
1
2
3
4
5
6
7
8
9 #include <iostream> using namespace std; class Chauffage { public: void fonctionChauffage(); };
Code:
1
2
3
4
5
6
7
8
9
10
11 #include "chauffage.h" void Chauffage::fonctionChauffage() { cout << "fabrication du chauffage" << endl << endl; } Chauffage::~Chauffage() { cout << "destructeur Chauffage" << endl; }
Je trouve que la classe suivante est "facile" à comprendre :
On peut appeler "marche" et "arret" sur un objet "Chauffage". On ne peut pas le construire "ex nihilo" (utilisation de DP pour construire correctement l'ensemble des objets de type "Chauffafe" en fonction de comment ils doivent être créés et "accédés").Code:
1
2
3
4
5
6
7
8 class Chauffage { protected : Chauffage(); public: void marche(); void arret(); }
Si on n'a besoin de plus d'action possible sur un objet "Chauffage", il faut juste l'ajouter à la classe les fonctions qui vont bien.
On n'inclus que les .h nécessaire à la compréhension du .h par le compilateur.Citation:
Code:#include <iostream>
Ici, le compilateur n'a pas besoin de "iostream" pour comprendre ce qu'il y a dans le .h.
Jamais de "using namespace" en globale dans un .h, et encore moins "using namespace std".Citation:
Code:using namespace std;
Déjà dans un .cpp, ça se justifie difficilement, alors dans un .h !!! :aie:
Je vous est déjà dit que ces "print coucou" sont largement substituables par des "break point" du débogueur.Citation:
Code:cout << "fabrication du chauffage" << endl << endl;
Si vous voulez des traces fonctionnelles, utilisez une MACRO ou un framework de trace, mais ne truffez pas votre code de "cout <<..." à la con.
Pourquoi un destructeur ? Vous comptez en faire une classe avec des classes filles ?
(Encore une fois, je pense que vous devriez prendre un peu de temps sur de "bons" cours de C++, qui abordent la notion de classes entité Vs classes "Valeurs")
Si vous commencez par pisser du code avant l'analyse, faites en sorte que votre code soit simple à comprendre et à utiliser au moins au départ.
Ça s'arrangera pas avec la progression du projet (sauf à faire des refactoring "douloureux").
Je pense que la lecture préalable d'un bon cours de C++ permettrait de plus facilement concevoir "correctement" des classes etc...
Il faut donc 5 objets/instances de classe "DS18B20" différent. Chacun initialisé avec une "adresse" différente.Citation:
car j'ai 5 sondes dans un fichier et elles ont leur propre fichier (adresse Ds18b20).
Code:
1
2
3
4
5 DS18B20 tempExt{"/sys/bus/w1/devices/28-3ce1e3804835/temperature"}; DS18B20 tempUnitExt{"/sys/bus/w1/devices/28-3ce1e3809744/temperature"}; DS18B20 tempEchExt{"/sys/bus/w1/devices/28-3ce1e38060ec/temperature"}; DS18B20 tempUnitInt{"/sys/bus/w1/devices/28-3ce1e3801251/temperature"}; DS18B20 tempEchInt{"/sys/bus/w1/devices/28-3ce1e3805e9f/temperature"};
Quand vous récupérez du code de l'"extérieur" assimilez-le, puis soit vous le transformez pour qu'il respecte vos conventions de codage, soit vous l'"isolé" dans des modules "externes".Citation:
pour le hpp, je sais pas trop car c'est une class que l'on ma fourni . je pense que c'est pour stipuler que c'est du c++, h++.
Ici, votre module "gpioPin" semble faire tampon entre votre code "métier" et le matériel.
Très souvent dans un projet informatique on sépare le code en 3 parties/couches : IHM, métier, data/matériel.
Ici, je pense que le module "gpioPin" est une partie de la couche "matérielle", car, si vous modifiez la partie physique du projet, cette partie du code devra être adaptée.
L'utilisation de "namespace" et de convention de codage différent entre les couches permet de mieux si retrouver.
Si un objet Modes a besoin de DS18B20 pour faire les services qu'il offre, oui, Modes soit avoir accès à des "DS18B20".Citation:
en gros l'ideal en que je doit mettre DS18B20 dans Modes ??
Mais je ne comprends pas vraiment ce qu'est concrètement ce "Modes".
C'est le meilleur moyen pour un faire truc qui ne fonctionne qu'avec ça présent et le jour où vous l'enlevez, c'est la catastrophe.Citation:
le sleep me sert a voir ce qu'il ce passe , si non cela vas trop vite , il sera retirer a la fin .
Ne truffez pas votre code de lignes inutiles, voire dangereuses. => Utilisez un débugueur.
Vous devez donc, avant de pisser du code pour votre projet, faire des POC avec les différent types de temporisation pour comprendre comment elles fonctionnent et donc correctement les utiliser pour la conception de votre projet.Citation:
les temporisations , oui sont tres important car elle servent pour actionner les diferents relais et controler les temperatures en fonction de l'etat ou le programme vas ce trouver a un temp donner .
Comme vous devez piloter du matériel, je vous conseille de commencer par des POC pour le pilotage de ce matériel.Citation:
et apres pour mettre a jour les temperatures sur l'ecran . mais pour l'instant avec vos conseilles est de construire le code metier et apres la partie ecran.
Votre code métier pourra utiliser les services offerts par cette couche matérielle.
La couche IHM utilisera la couche métier.
Non, elle sert à modéliser le comportement et les services offerts par un ensemble d'objets/instances.Citation:
la class sert a creer un objet .
C'est normal, ne vous inquiétez pas. faut que ça murisse.Citation:
et j'avoue que ce n'ai pas si evident que cela !
la je suis completement perdu !
pour chauffage , j'ai penser a un switch case pour passer d'un etat a un autre :
est ce une bonne idée?
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 #ifndef CHAUFFAGE_H #define CHAUFFAGE_H #include <cstdio> class Chauffage { enum { MARCHE_CHAUFFAGE, CONTROLE_TEMPERATURE_CHAUFFAGE, TEMPO_COMPRESSEUR_CHAUFFAGE, CONTROLE_TEMPERATURE_VENTILATION_INTERIEUR, TEMPO_DEGIVRAGE_CHAUFFAGE, MODE_DEGIVRAGE_CHAUFFAGE, TEMPO_DEGIVRAGE_V4V, TEMPO_DEGIVRAGE_COMPRESSEUR, CONTROLE_TEMPERATURE_DEGIVRAGE_ELECTRIC, DEGIVRAGE_NATUREL, EGOUTTAGE_CHAUFFAGE, FIN_EGOUTTAGE_CHAUFFAGE, ARRET_CHAUFFAGE, } etatsChauffage; public: Chauffage(); ~Chauffage(); void fonctionChauffage(); }; #endif //CHAUFFAGE_H
pour l'instant j'ai mis printf();Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72 #include "chauffage.h" Chauffage::Chauffage() { } void Chauffage::fonctionChauffage() { printf("fabrication du chauffage \n\n"); switch(etatsChauffage) { case MARCHE_CHAUFFAGE: break; case CONTROLE_TEMPERATURE_CHAUFFAGE: break; case TEMPO_COMPRESSEUR_CHAUFFAGE: break; case CONTROLE_TEMPERATURE_VENTILATION_INTERIEUR: break; case TEMPO_DEGIVRAGE_CHAUFFAGE: break; case MODE_DEGIVRAGE_CHAUFFAGE: break; case TEMPO_DEGIVRAGE_V4V: break; case TEMPO_DEGIVRAGE_COMPRESSEUR: break; case CONTROLE_TEMPERATURE_DEGIVRAGE_ELECTRIC: break; case DEGIVRAGE_NATUREL: break; case EGOUTTAGE_CHAUFFAGE: break; case FIN_EGOUTTAGE_CHAUFFAGE: break; case ARRET_CHAUFFAGE: break; } } Chauffage::~Chauffage() { }
j'aimerais comprendre , avec votre aide TRACE ou MACROS et de savoir le mieux pour vous pour mon style de projet ?
c'est surtout pour avoir des infos sur le terminal pendant l'excution du code.
pour les DS18B20 j'ai compris .
Modes est en faite la partie principale, il gere en fonction du thermostat et de la temperature le mode qu'il doit etablir (chauffage ou froid).
j'ai retirer le sleep!
pour les temporisations je suis a votre ecoute car je ne trouve pas grand chose sur POC sur google , sauf si je mi prend mal.
je vous avoue que je suis dans le brouillard total car en faites il ya vraiment tous et son contraire sur le net pour coder :mur:
Hello,
Un switch / case (gargantuesque) pour gérer les états, c'est très naïf, et à la longue pas maintenable.
Cet article peut t'intéresser:
https://www.aleksandrhovhannisyan.co...achine-in-cpp/
Concernant les operateurs new:
En C++ moderne, on aime pas cet opérateur.
D'une part, il requiert l'opération inverse (l'operateur delete), ainsi que les pointeurs nu dont on ne peut garantir la validité (l'objet pointé est-il toujours en vie ? Qui en est le propriétaire ?), autant de sources d'erreurs dependantes de la discipline du programmeur, en d'autre thermes: Incertaines.
C++ a introduit depuis la norme C++ 11 les pointeurs intelligents (std::unique_ptr, std::shared_ptr) qui gomment de nombreuses faiblesses des pointeurs nu, et permettent entre autre de se concentrer sur les comportement des classes plutôt que la gestion de la memoire.
Illustration avec les extrais de code suivant:
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 // Avec l'operateur new #include <iostream> #include <new> #include <cstdlib> int main() { int* number; try { number = new int; std::cout << "New integer allocated" << *number << std::endl; } catch(std::bad_alloc& e) { std::cerr << "Memory allocation failed: " << e.what() << std::endl; return EXIT_FAILURE; } *number = 10; std::cout << "Value: " << *number << std::endl; delete *number; return EXIT_SUCCESS; }
Code:
1
2
3
4
5
6
7
8
9
10
11 // Avec les pointeurs intelligents #include <iostream> #include <memory> #include <cstdlib> int main() { std::unique_ptr<int> number{ std::make_unique<int>(10) }; std::cout << "New integer allocated, value: " << *number << std::endl; return EXIT_SUCCESS; }
Comme le montre la référence donnée par @deedolith, il est "facile" de trouver des solutions "clés en main" de problèmes "généraux" car le C++ est un langage très mature et donc sert souvent d'illustration à la résolution de ces problèmes.
Mais le Net est truffé de mauvais codes et de mauvais cours de C++, dû au manque de "sélection naturelle" de ce qui sort les recherches Google ou les IA génératives, et à l'évolution du langage depuis les années 1980.
Les vieux machins écris par des personnes venant du C ou qui ont une vue très superficielle des spécificités du C++ "moderne"(>=C++11, en 2011) "bien écris" squattent les référencements.
C'est pour cela qu'on vous recommande de lire un bon cours "à jours", comme celui de Zeste de Savoir, pour que vous puissiez rapidement évaluer si le code que vous trouvez sur le Net est merdique ou pas.
cf. les 2 paragraphes précédents.Citation:
je vous avoue que je suis dans le brouillard total car en faites il ya vraiment tous et son contraire sur le net pour coder :mur:
Je crois que @deedolith a déjà répondu.Citation:
pour chauffage , j'ai penser a un switch case pour passer d'un etat a un autre :
Vu la complexité du machin, il faudrait que vous dessiniez un schéma d'états : un schéma avec des ronds pour chaque état de l'objet et des flèches entre chaque état qui indique comment/pourquoi on passe d'un état à un autre.
Je serai très surpris que votre schéma d'états ne soit composé que de 13 ronds et de d'une flèche qui sort de chaque rond avec comme label "fonctionChauffage".
Construisez votre schéma sans rien codé, juste avec la "réalité".
Je pense qu'il y aura beaucoup moins que 13 états et qu'il y aura plus qu'une flèche par état.
Si votre schéma d'état est clair, le code qui l'implémentera sera bien plus simple à faire.
Votre enum est privé à votre classe. C'est logique si aucun autre élément de votre projet n'a à connaitre l'état du chauffage, mais est-ce vraiment le cas ?
Il est toujours préférable de commencer le plus "privé" possible, mais il faut que cela soit en accord avec votre conception.
Avant même de commencer à coder, vous devez déjà avoir répondu à ce type de question : "qui sait quoi".
"etatsChauffage" c'est UN état et il n'est connu que de la classe Chauffage, et l'enum est un type, pas un champ ou un autre type de variable.
Donc, c'est plus "logique" de nommer l'enum "StateType" et un champ dans la classe Chauffage de nom "state" et de type "StateType".
Le constructeur de votre classe Chauffage est public, vous faites donc de cette classe Chauffage une classe "Valeurs" ; moi, je pense que c'est plus une classe Entity car je ne vois pas l'intérêt de pouvoir "créer/cloner" un objet Chauffage à tout moment dans votre code. Ne devrait-il pas être privé ?Code:
1
2
3
4
5
6
7
8
9
10
11 class Chauffage{ enum{ ValeurParDefautDeLEtat, .... } StateType; StateType type; ... public: ... }
Idem pour le destructeur : Entité VS Valeurs.
Essayez de garder le code de vos constructeurs et destructeurs proches les uns des autres pour facilement respecter la règle des Cinq : https://www.geeksforgeeks.org/cpp/rule-of-five-in-cpp/
C'est toujours aussi peu pratique.Citation:
pour l'instant j'ai mis printf();
Exemple d'une MACRO "TRACE" qui permet d'automatiquement gérer du code ASCII/UNICODE et d'avoir accès au nom du fichier et la ligne du code qui a généré cette trace.
Ici, pas de gestion de niveau de trace mais ce que je vous demande c'est d'une, de ne pas mettre des traces inutiles/abscons n'importe où n'importe comment ; et d'utiliser des Framework de trace qui, eux, gèrent ces niveaux.Code:#define TRACE(sz) printf(_T("%Ts (%Ts:%d)\n"),_T(sz),_T(__FILE__), __LINE__)
Pour utiliser la MACRO :
Pour utiliser la MACRO, faut juste faire en sorte que le code qui l'utilise ajoute le #include du fichier qui définit la MACRO.Code:
1
2
3
4
5 void Chauffage::fonctionChauffage() { TRACE("fabrication du chauffage"); ... }
Comme je vous ai déjà indiqué qu'il vaudrait mieux "stratifier" votre code en "Hardware/Métier/IHM", vous pouvez très bien avoir une définition différente de cette MACRO en fonction de la couche.
Ainsi, il est très probable que les module de la couche "Hardware" qui doivent pouvoir fonctionner sur tous les systèmes capables d'héberger le hardware, même sans console, la trace n'utilisera préférentiellement pas "printf" mais des truc plus bas niveau, comme qemu.
Donc, arrêtez de faire des traces comme un poulet sans tête !!!
Si vous avez besoin de trace, utilisez un Framework de trace. Et vous êtes encore très loin d'en avoir besoin.
Le débugueur est vôtre ami.
Comme je l'ai déjà écrit ci-avant, il y a de grosses chances que chaque strate de votre projet est des besoins différents, donc potentiellement des Frameworks différents.Citation:
j'aimerais comprendre , avec votre aide TRACE ou MACROS et de savoir le mieux pour vous pour mon style de projet ?
Utilisez une MACRO proche de TRACE (en ajoutant des niveau de trace par exemple) dans chacune des couches de votre projet, pour pouvoir changer de Framework facilement, juste en modifiant la MACRO.
Vous allez surtout flooder votre terminal avec des "informations" totalement abscons.Citation:
c'est surtout pour avoir des infos sur le terminal pendant l'excution du code.
Il vaut mieux peu de traces pertinentes qu'une montagne de données sans aucun sens, vous n'êtes pas (encore?) une IA.
Réfléchissez "bien" à votre trace, au niveau de détails aux quel elle correspond, avec une mise en forme claire, cohérente, systématique => utilisez un Framework et arrêtez de faire du "bricolage".
Gérer 2 choses, c'est gérer 1 chose de trop. :aie:Citation:
Modes est en faite la partie principale, il gere en fonction du thermostat et de la temperature le mode qu'il doit etablir (chauffage ou froid).
Le Thermostat doit être gérer par un objet Thermostat.
Une température par un objet Températures.
Si c'est le système au complet, pourquoi ce n'est pas un objet de class "ThermalSystem" ??? (donc sans constructeur public, ok ? ;) )
Il faut que vos noms soient clairs, quitte à l'expliquer à un canard en plastique, ou à l'enfant le plus dissipé de l'adelphie.
"Modes", c'est pas clair.
POC, c'est Proof Of Concept. https://fr.wikipedia.org/wiki/Preuve_de_conceptCitation:
pour les temporisations je suis a votre ecoute car je ne trouve pas grand chose sur POC sur google , sauf si je mi prend mal.
Avant d'investir des heures, des années et des millions dans un projet sans savoir si c'est possible ou sans maitriser les concepts clés du projet, on fait des programme "jouet" pour valider chacun des trucs qu'il faut maitriser.
Avant de faire de la temporisation dans votre projet, faite des projets "jouet/d'exemple" pour tester comment fonctionnent les différents systèmes de temporisation.
Avec des programmes "jouet", vous pouvez facilement tester tous les cas nécessaires à votre compréhension des trucs, sans avoir à "saloper" votre projet pour faire des tests.
J'ai déjà mentionné "std::async", avez vous essayez ? Correspond-t-il à vos besoins ? (intéruptionnabilité ? multi-thread ou pas ? disponible sur votre plateforme de test ? de production ? etc...)Vous devez savoir de quoi vous avez besoin pour choisir le ou les bons systèmes de temporisation.
bonjour , j'ai fait mon diagramme , dite moi ce que vous en pensée et si c'est + parlant.
merciPièce jointe 669023
Ok, c'est comme ça que vous appréhendez le projet ?
C'est complexe de base.
Vous n'avez pas une approche "objet" ni "procédurale".
Pouvez-vous revoir ce diagramme avec une approche objet ou procédurale ?
Essayez de vous raccrocher aux composants logiciels que vous comptez utiliser. Pour éviter d'avoir à trop galérer avec.
Faites un prototype avec les fonctionnalités prioritaires.
un diagramme de ce style ? :
Pièce jointe 669045
Votre diagramme ressemble à un diagramme de classe, pas un diagramme d'objet ou à un cas d'usage.
La distinction classe/objet me semble toujours pas assimilée.
Dans un diagramme d'objets, il y a des objets qui ont souvent la même classe.
Donc si c'est un diagramme de classe : DS18B20 ne contiendra pas 5 attributs/champs "Sonde", la classe Temporisation n'aura pas 7 attributs/champs de type "temporisation" (???), etc...
Mais la classe DS18B20 aura UN attribut/champ "Sonde" (l'@ sur le bus ?) et la classe "Temporisation" un attribut/champ "Alive" et/ou un attribut/champ délai avant déclenchement.
Des champs qui permettent de faire avec des instances/objets de ces classes des choses "utiles".
Comme demander une température à une Sonde "DS18B20", ou dans combien de temps se déclenchera la temporisation, etc...
Avec les Frameworks de temporisation existants, je ne suis pas sûr qu'avoir sa propre classe de "Temporisation" soit très utile.
Des objets doivent regrouper des services qui fonctionnent ensemble.
Par exemple, dans votre diagramme, la classe "Gainable" (pensez à utiliser des conventions de codage comme les noms de classe/type commencent une majuscule et les noms d'objet/variables par des minuscules ( Oui, le C/C++ n'applique pas ces règles mais c'était dans les années 1970 :aie:)) est un très bon exemple de classe qui rend des services "clairs".
On peut lui demander de lancer ou d'arrêter le chauffage ou le froid et l'une des fonctionnalités qu'elle peut implémenter en interne est d'arrêt de chauffage automatiquement si on lui demande de lancer "le froid" (ou d'interdire le lancement du froid avant d'avoir éteint le chauffage, mais je trouve que ce type de service moins pratique).
Après, cette "synchronisation" entre le Froid et le chauffage, est-ce du ressort d'un objet "Gainable", qui me semble un machin physique, ou d'un objet purement logique/logiciel comme un "ThermalSystem" ?
Les noms des classes/variables etc..., c'est très important.
En regroupant des actions "logiquement" dans des "fonctions" des objets, vous devriez réduire considérablement la complexité d'un diagramme comme celui de https://www.developpez.net/forums/at...diagramme.pdf/.
La classe "thermostats" :
- préférerez mettre des majuscules pour les noms de types => "Thermostats"
- évitez d'utiliser des "s" terminaux pour distinguer les regroupements d'objets mais plutôt utilisez un suffixe qui correspond à l'API de regroupement qu'il implémente => "ThermostatArray" ou "ThermostatList" etc...
- Avoir un attribut/champ de même type que la classe, c'est assez rare : implémentation de liste chainée "old school" ou d'un singleton
mais c'est jamais du type "brut", pour une liste chainée, c'est avec des pointeurs (*Thermostats) et pour un singleton, ça serait une instance de classe/statique (Thermostats static getInstance()).
donc, essayez d'être explicite sur ces "décorations" (static, *, const, m_, s_ etc...), ça rend le schéma sera plus précis mais aussi bien plus clair.
- Les actions "arret" et "marche", si on interprète "Thermostats" comme un regroupement de "ThermostatS", l'action "xxx" propage l'action à l'ensemble des instances du groupe ???
Pour les action/opération, essayez de suivre une règle de codage type "nom commençant par un verbe d'action puis le périmètre de l'action":
Ici, ça donnerait des noms "Arreter" et "Demarrer", ou encore si c'est pour un termostat unique "ArreterUnThermostat(std::wstring key)" et "DemarrerUnThermostat(std::wstring key)", etc...
La classe Relai (relais?), c'est beaucoup beaucoup trop complexe et vague, vraisemblablement ambiguïté entre classe et instance/objet.
Essayez de lire un cours complet sur le C++ ou tout du moins la POO pour rendre ces diagrammes "clairs" et efficaces.
https://www.academie-francaise.fr/si...tions_1990.pdf
Malheureusement, il s'agit là d'une des catastrophes introduites par la réforme orthographique de 1990. :no:
J'étais personnellement en classe de 4ème quand elle a eu lieu et personne, ni élève ni enseignant, n'avait jamais eu l'idée d'appliquer ces recommandations. Il y avait même eu une opposition forte aussi bien des adultes que des jeunes à l'époque et personnellement, j'ai toujours préféré appliquer une orthographe aussi traditionnelle que possible.
Ce qui m'étonne, en revanche, c'était que j'étais resté persuadé que cela ne concernait que des détails mineurs et que l'on devait les horreurs telles que « relai » ou « ognon » (si, si) à une circulaire assez récente. C'est même à cette époque que les magasins « le relais », par exemple, sont devenus « relay » dans les aéroports et les gares, histoire de couper la poire en deux. Par contre, impossible de retrouver cette directive et après quelques années, il semble que les gens aient fini par l'abandonner d'eux-mêmes.
Ma remarque n'était pas liée aux "s" mais plus à la Case.
Et pour le coup, j'exècre l'approche Académie Française qui veut faire du Français un putain de Musée poussiéreux à centrifugeuses d'entre-soi intégrée.
Une langue qui n'évolue pas est une lague morte.
Donc "Vive Relai", même si, dans le diagramme du PO (Posteur Original), il fait bien trop de choses => "RelaySet" :aie:
P.S.: en 1990, je passais le BAC et bien formaté par cette éducation nationale "conservative" et "CSP reproductive", bien plus hussarde de "la bien-pensance bourgeoise" que de la "république".
Et les statistiques actuelles montrent que ça bien empiré depuis.
Sans la dernière réforme de l'orthographe du XIXème, "acceptée partiellement par l'académie", on serait toujours avec des "hostel" des "forest" des "estoit" (à la place d'était) des "sçavoir" (à la place de savoir), etc...(et ognon était déjà au programme mais les gardiens du Musée/académiciens aiment bien leurs horreurs logiques : on les remercie pour les 4 fois plus de dyslexique en France qu'en Italie ou en Espagne) .
Et on passera sur le foutage de gueule étymologique du "nénuphar" de Blanquer, c'est du farsi pas de grec, nénufar bordel !!!
Ca pique aussi pour moi. :aie:
Je suis d'un âge certain et ma plasticité mentale n'est plus. :fou:
Mais comme une classe "relais" surplombe une classe "thermostats" avec des machins pas clairs sur "groupement ou pas", c'est mon cerveau d'analyse codesque et pas mon cerveau traumatisé à grand coup de dictées de primaire qui est en charge de mon système 1 (automatisme énergético-économique). :lefou:
C'est aussi pour ça que programmer en anglais, c'est plus "simple". (malgré les wolf => wolves ou autres half => halves, etc... )
Désolé, je suis assez chatouilleux sur la "prescriptivité" des éditorialistes du Figaro sur cette panique morale de "tout fout le camp".
Merci pour ta bienveillance @Obsidian, malgré mon attitude de "tro* d* cu*". :oops:
@ludoiphone, les noms sont importants, mais la simplicité/logique surpasse "la grammatico-synthaxico-lexico-exactitude" des académiciens en carton. :king:
En effet, et c'est souvent beaucoup plus concis ! Et ça ne date pas d'hier. La langue est beaucoup plus ancienne que nous, naturellement, mais quand il fallait coder sur quarante colonnes et 64 Ko de mémoire, ça prenait tout son sens.
Tu mets aussi le doigt sur un point particulier : le choix du pluriel ou du singulier dans les conventions de nommage. Le bon sens « technique » nous suggère d'utiliser le singulier partout mais à l'usage, ça va souvent à l'encontre des habitudes lorsque le pluriel se justifierait dans le langage courant…
merci,
j'ai fais des modifications sur : https://github.com/ludoiphone/gainab...tion/tree/main
aprés c'est un peut le brouillard , je suis completement perdu .
j'ai tous le fonctionnement en tete (voir le diagramme : Diagramme.pdf)
mais le plus difficile est de le transformer en code et surtout dans les regles de l'art pour un debutant.
je sais plus par ou commencé !! et quoi utiliser , ca me deprime!
de lire les cours POO c'est toujour sur des traitement text mais jamais dans ce que je souhaite faire .
est que les class ne sont pas compatible avec mon projets ??
C'est normal de galérer, mais on voit que vous avez "fréquenté" de mauvaises sources d'information.Citation:
aprés c'est un peut le brouillard , je suis completement perdu .
Vous avez de "mauvaises habitudes" qu'il faudra combattre, malheureusement.
C'est pour cela que j'insiste pour que vous preniez un peu de temps pour lire un "bon" cours de C++ comme celui de Zeste de Savoir, rapidement.
Et c'est un très bon début.Citation:
j'ai tous le fonctionnement en tete (voir le diagramme : Diagramme.pdf)
Le problème, c'est qu'il faut faire comprendre à un truc aussi débile qu'un ordinateur ce fonctionnement "désiré".
(Il y a peut-être des "trous" dans la conception de votre diagramme, mais je n'ai pas les connaissances pour le savoir.)
La boutade du canard en plastique n'est pas qu'une simple plaisanterie, c'est une vraie méthode d'externalisation des problématiques de programmation.
Votre question initiale était liée à l'utilisation de Qt, qui est une librairie C++ qui utilise massivement la POO.
Nous avons donc répondu en faisant l'assertion de la "maitrise" de la POO.
Ce n'est vraisemblablement pas le cas.
Le C++ est un langage multiparadigme, on n'ai pas obligé de faire de la POO (contrairement à JAVA ou C#), mais beaucoup d'outils du C++ reposent plus ou moins sur la POO.
C'est donc assez compliqué de s'en passer.
Désolé si nos conseils font très "règles de l'art", mais ce n'est que des conseils pour vous "simplifier" l'utilisation des outils qui nous sont offerts.Citation:
mais le plus difficile est de le transformer en code et surtout dans les regles de l'art pour un debutant.
Commencez par des POC.Citation:
je sais plus par ou commencé !! et quoi utiliser , ca me deprime!
Des petits projets qui ont pour but de comprendre des choses de manière isolé.
- Récupérer une température
- Récupérer plusieurs températures
- Actionner un machin dans le système.
- Actionner un machin dans le système en fonction d'une température.
- Récupérer une température durant un certain temps à une cadence donnée.
- etc...
Il y a de grandes chances que vous ne récupériez pas le code créé pour ces POC mais vous aurez de bonnes bases pour commencer le "vrai" projet.
LOL, le "traitement de texte", c'est un cadre d'expérimentation créé par le "Gang of Four" (https://www.digitalocean.com/communi...esign-patterns) pour présenter dans les années 1990 différents Design Patterns, outils encore assez expérimentales à cette époque.Citation:
de lire les cours POO c'est toujour sur des traitement text mais jamais dans ce que je souhaite faire .
Quand vous faites un bouquin ou un cours, il est très attrayant de faire cela dans un "contexte" particulier, pour ne pas avoir à présenter un nouveau contexte pour chaque notion à aborder.
Ce contexte n'est là que pour créer un cadre d'expérimentation.
Celui du "traitement de texte" est clairement fait pour des personnes qui maitrise déjà assez bien la POO, lectorat cible du bouquin du "Gang of Four".
Dans ce forum, @koala01, un très gros intervenant ici, a écrit un bouquin sur comment bien écrire du code et a pris comme contexte la programmation d'un jeu d'échec, correspondant vraisemblablement au lectorat cible de son bouquin.
Vous devez être capable de vous "extraire" du contexte particulier d'un cours ou d'un bouquin. Ce n'est qu'une illustration de l'utilisation de concepts bien plus génériques que ce contexte particulier.
Oui, mais êtes-vous déjà compatible avec les classes ?Citation:
est que les class ne sont pas compatible avec mon projets ??
La POO a largement fait ces preuves depuis les années 60 (mais la conception objet a évoluée depuis, utilisez des sources récentes et de qualité, SVP).
Ce n'est pas forcément le paradigme de programmation le meilleur pour votre projet ou pour vous.
Mais en C++ il est central, bien que non nécessaire.
Essayez de faire de simples POCs, en vous passant de la POO, si nécessaire.
Vous n'avez pas appliqué nos conseils, pourtant assez directifs (trop directifs peut-être ?), comme le fait que DS18B20 fait trop de chose à la fois et mélange vraisemblablement classes et objets.
Que le constructeur de DS18B20 devrait avoir paramètre donnant le chemin vers la sonde.
Que le constructeur et le destructeur doivent être ensemble,
Que les variables globales, c'est mal.
Réduire au maximum le nombre d'include dans les .h
dans gpioPin.hpp, essayez d'utiliser le même niveau de "modernité" dans un même composant logiciel => utilisez "#pragma once" à la place de header guards "old school".Citation:
#pragma once
Dans "main.cpp", la variable "chrono" est utilisée avant d'être initialisée (votre compilateur aurait dû vous le signaler, non ?).
"production", c'est bizarre comme "Action" à faire.
Vous n'avez pas appliqué le conseil de "au lieu de faire des SetBidule partout, passez des objets qui permettent d'avoir l'information aux objets qui ont besoin de cette information".
Exemple :Citation:
Code:mode.SetTemperatureExt(sondeExt.GetTempExt());
Code:
1
2 DS18B20 temperatureExt; System system{temperatureExt};
Donc un "ContactThermostat", c'est un booléen ???Citation:
Code:bool GetContactThermostat
Je pense toujours que la lecture préalable d'un bon cours de C++ "moderne" serait très productif.