On écrit "J'ai tort" ; "tord" est la conjugaison du verbre "tordre" à la 3ème personne de l'indicatif présent ;)
Coucou tout le monde
Coucou bacelar
Ta proposition de TRACE() avec _T est spécifique à Windows; or, je crois que le "poster" tourne sur "RPI", du Linux donc.
Ça fait très longtemps que je n'ai pas pratiqué, mais j'ai souvenir d'une bibliothèque multiplateforme qui fait le job, "spdlog".
Si l'on ne veut pas s'encombrer avec, voici une version sommaire et portable de "TRACE()". Elle s'activera lors d'un "Build" (construction) de type "Debug".
Je viens d'ajouté "sommaire" parce que tu as très justement abordé le problème du "flood" du terminal. À ce sujet, dans la version plus complète que j'avais écrite, il y avait du TRACE à toutes les sauces: TRACE_RED, TRACE_GREEN, etc., TRACE_LEVEL, TRACE_WARNING, TRACE_TITLE, TRACE_BEEP, etc., etc., et effectivement ça aide pas mal.
Mais encore une fois, "spdlog" peut faire le job.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 //Overview of a C++ TRACE() implementation //This header must be included before all others in each source file. #pragma once #if ! defined NDEBUG #define DEBUG_MODE_ENABLED 1 #else #define DEBUG_MODE_ENABLED 0 #endif enum {debug_mode_enabled= DEBUG_MODE_ENABLED}; #include <cstdio> //Variadic Macros, officially since C++11 (and C99 for info), but maybe before as compiler extension #define TRACE(...) do {if (debug_mode_enabled) std::fprintf(stderr, __VA_ARGS__);} while(0) //Must be used like printf(), for example: //TRACE("Hello, %s!", "trace");
En tout cas c'est un comportement indéfini, et sur PC, généralement un segfault.
C'est peut être une coquille, mais je compte 4, voire 6 autres problèmes.
Aussi dans le deuxième code, std::make_unique peut lancer une exception. Mais, contrairement au premier, ce n'est pas souligné. Ça laisse croire que la gestion des exceptions devient inutile avec les "smart pointers". En l'état, les deux codes ne sont pas comparables.
L'appareil que j'utilise à cet instant ne permet pas la consultation des PDF en pièces jointes. Des images et du texte dans le corps des messages auraient été préférables.
Je ne vais pas épiloguer sur les difficultés du langage C++ mais il ne faut pas se priver d'en explorer d'autres. Plus on est à l'aise avec un langage et mieux c'est, si c'est un langage qu'on aime, c'est encore mieux.
Cela dit, le fait d'avoir déjà un projet est un atout. Il faut sélectionner une portion de C++ qui va bien, quelques briques logiciel, et ce sera sur les rails.
Mais ATTENTION!!! L'aspect sécurité des personnes est ici primordial. Si vous n'êtes pas en mesure de l'assurer côté matériel, ne vous engagez pas dans cette voie. Je passe sous silence les problèmes de normes, réglementations, certifications pour lesquels vous êtes certainement au fait. Mais surtout, pensez à bien vérifier votre marge de manoeuvre par rapport à votre contrat d'assurance habitation. Ce genre de négligence ne pardonne pas.
Pour en revenir à l'objet de la discussion, si je traduis bien, il y a deux systèmes chaud, froid, et le but est qu'ils ne fonctionnent pas en même temps. Ensuite apparaissent les soucis de la mise en forme de tout ça. J'y reviendrais.
Pour le premier point, le plus accessible pour un débutant c'est encore de coller à la réalité. Quand il y a un système de chauffage et un autre de climatisation, généralement, il y a un surensemble qui gère le tout, plus ou moins. Le "plus ou moins" c'est parce qu'il existe un troisième système asservi qui est le thermostat d'ambiance.
Son rôle est de réclamer la production de chaleur ou de fraicheur en fonction de sa programmation et des températures des milieux dont il a la charge.
Pour ce qui est du transport et de la distribution de cette énergie produite, les manières de faire sont tellement nombreuses que, dans les faits, ce n'est qu'une extension du système.
Bref, ce surensemble peut s'appeler une pompe à chaleur, un climatiseur réversible, une bouillote... qu'importe ...
Du point de vue du code, ça pourrait donner ce genre de composition: (c'est du vrac, une illustration)
Je fais l'effort d'y mettre un peu de français pour ne pas perdre l'intéressé.
Cette classe n'a pas besoin d'être plus fournie. Comme énoncé précédemment, j'ai anticipé le problème des "while (1)", de Qt (qui peut être invasif), et la façon dont l'intéressé aborde ces choses. En effet, il y a souci de partage des responsabilités et d'orchestration du tout.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 class Froid; class Chaud; enum Mode {OFF, CHAUFFAGE, CLIM, AUTO, MAINTENANCE}; enum class Sub_Mode_Chauffage {ECO, COMFORT}; // dans l'optique du patron "stratégie" introduit par Bacelar //... class PAC // pompe à chaleur { public: void enable_chaud() {froid.disable(); chaud.enable();} void enable_froid() {chaud.disable(); froid.enable();} void disable() {froid.disable(); chaud.disable();} std::string get_status() const { return froid.get_status()+ " | "+ chaud.get_status();} //void set_mode(Mode m) {mode= m;} //... private: Chaud chaud; Froid froid; //integrated thermostat //Sonde exterieur{id_abc}; // //Sonte interieur{id_def}; //Sonde sejour{id_ghi}; //and/or maybe //Thermostat remote_thermostat; //... std::atomic<Mode> mode{OFF}; // => #include <atomic> };
Compte tenu des bouts de codes écrits par le "poster", je pense qu'il sera plus à l'aise avec une architecture MVC (model-view-controler, modèle-vue-contrôleur).
La vue, c'est l'interface utilisateur, le contrôleur, c'est l'objet PAC, le modèle serait une ou plusieurs structures/classes de données (), intégré à PAC, ou pas, alimenté par ce dernier, et utilisé par la machine à états.
Elle-même pourra y écrire des données qui seront lues par PAC, éventuellement aussi par un terminal de monitorage. Il y a de quoi faire, tout dépend du degré de sophistication recherché.
très schématiquement:
par exemple, PAC::Mode peut être considéré comme un modèle. (conf. la ligne avec Mode mode{OFF}; )
Code : Sélectionner tout - Visualiser dans une fenêtre à part view(s) <-> controler(s) <-> model(s) <-> (finite-state) machine ( |hardware)
Cette fonction (qui s'appelle un arbre de décision), en même temps qu'elle s'allongera, vous ressentirez le besoin de factoriser.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 void run_machine(const PAC& pac) { //may be (later) PAC member function: void PAC::run_machine() { // or void run_machine(const Model& model) { //Trace only when the state changes //something like: auto trace_condition{ __LINE__ }; // <= (reminiscence) TRACE_CONDITION_INIT(optional_condition_type(BASIC | TREE), opt_name, opt_condition); while (pac.get_mode() != SHUTDOWN) { //or (model.mode != SHUTDOWN) // or ( ! must_exit()) std::this_thread::sleep_for(std::chrono::seconds(1)|1s); //prevent high CPU load if (pac.termostat.wath_requested() == Request::heating) { if (pac.get_mode() == CHAUFFAGE) { //auto debug_mode_enabled= DEBUG_MODE_ENABLED & (__LINE__ != trace_condition); trace_condition= __LINE__; // <= TRACE_CONDITION_NOTRACE_ON_MATCH(..); _ON_MISMATCH(...); TRACE("Production et acheminement de la chaleur en cours...\n"); TRACE("Utilisation de l'algo %s...\n", (pac|termostat).get_sub_mode_chauffage_name()); } else { //TRACE_CONDITION_NOTRACE_ON_MATCH(..) TRACE("Production de chaleur requise par le thermostat, mais interdite par le PAC.\n"); } // .... } turn_off_hardward(); }
Il s'en dégagera très vite des unités logiques, que vous pourrez modéliser, dans de simples fonctions ou en classes pour avoir quelque chose de "SOLID" (conf. définition sur Wikipedia) suivant vos progrès, évidemment.
Par ailleurs, c'est aussi une forme simple de machine à états, elle permettra de faire comprendre votre raisonnement et à vous de vous organiser, avec l'impératif que la boucle doit tourner continuellement, donc pas d'autre "pause" que le seul std::this_thread::sleep_for déjà en place.
Une bibliothèque d'automate simple toute faite aurait été préférable, mais je n'en connais pas. Faute de mieux, vous pourrez au moins avancer sur votre projet.
Bon, il faut que j'abrège.
Peut-être un mot pour la temporisation, qui peut se faire avec un chronomètre
Pour avoir quelque chose de rapidement fonctionnel, utilisez les threads (fils d'exécutions) (c++20 std::jthread).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 start= std::chrono::steady_clock::now(); // => #include <chrono> ... if (this_state_is_in_progress()) { if (std::chrono::steady_clock::now() - start > tempo) {set_next_state();} } //
Éventuellement, des fonctions libres. Faites tout dans un seul et même fichier (.cpp) pour garder une vue d'ensemble.
Déplacez au fur et à mesure les blocs de code "matures" qui vous en empêchent.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 void input(PAC& pac) { //input interface, std::cin, IHM: TUI (ncurses), GUI (frameworks Qt, wxWidgets, ImGUI), Interface-Machine-Machine (IPC...), RPC, ... while (wait_for_user_request && user_request != exit_request) { pac.deal_with(user_request); } //maybe at first: pac.set_mode(SHUTDOWN); } void output(const PAC& pac) { //ouput interface, std::cout, IHM widgets... while (waiting_for_signal, _for_callback or _for_countdown*) //* = polling (scrutation) output_interface(pac.get_status()); } int main() { PAC pac; auto machine{std::jthread{run_machine, std::ref(pac)}}; // => #include <thread> auto output_view{std::jthread{output, std::ref(pac)]}; input(pac); }
PS @Les-poteaux
Je viens de taper sur un minuscule clavier... donc, désolée pour les fautes...
Oui parce qu'à la base, je voulais juste faire un petit coucou ...
Allez, @++
merci a vous tous ,
la comprehension de kaitlyn sur mon projet est au top ! merci.
apres , j'aimerai commencer peut-etre par revoir le code des DS18B20 pour comprendre petite a petit (doucement mais surement) .
au final j'ai changer la bibliotheque de mes pins , je vais utiliser WiringPi (tres connu).
puis la methode de TRACE me plait bien , mais en vous lisant j'ai essayer de l'inclure dans mon code , mais je ne vois pas trop comment faire pour le compiler avec cmake , si vous avez un exemple merci .
je vous remerci a tous du temps que vous m'accorder.
Salut tout le monde,
Pour intégrer TRACE() à ton projet, il suffit de copier le code correspondant dans un fichier d'entête (.h), ensuite d'inclure ce dernier dans tous tes fichiers sources (.cpp) et avant toutes les autres inclusions.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 #include "le_fichier_de_trace.h" /* il contient le code précédemment présenté. */ #include <blablabla> //ect int main() { TRACE("je trace..."); }
Le fichier d'entête ne changera rien par rapport à CMake, ce n'est pas une source, il ne peut pas être compilé.
De même, je n'ai pas d'exemple de CMake à te fournir, car j'imagine que c'est en rapport avec Qt.
Cependant, une rapide recherche montre qu'il y a ce qu'il faut sur leur site :
https://doc.qt.io/qt-6/cmake-get-started.html
https://doc.qt.io/qt-6/cmake-manual.html
Salut,
J'ai une petite anecdote sympa.
Hier soir, j'ai visionné le 4e opus de la saison 3 de Foundation, une adaptation des romans d'Isaac Asimov.
Le Frère au Grand Jour (l'Empereur Cléon) s'adresse à Demerzel (androïde féminin) en ces termes (de mémoire):
Pour le contexte, Demerzel a effacé la mémoire de l'amoureuse de Cléon, puis l'a congédiée. Il est très en colère.
Cléon: Sais-tu ce que c'est que d'avoir une connexion profonde avec l'être aimé ?Demerzel: Oui ! J'ai été conçue pour avoir des connexions avec mes semblables. On appelle ça l'entrelacement, au point de ne former qu'un.Cléon: Oh! Un peu comme un thermostat parle à une chaudière ? C'est vrai que c'est très intime. Au temps pour moi.![]()
salut a vous , j'essais de comprendre
enum Mode {OFF, CHAUFFAGE, CLIM, AUTO, MAINTENANCE}; ca je comprends.
ce que je comprend pas :
et comment faire pour le get_mode ?? dois je creer un switch case ou autre en return le enum Mode ??
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 std::string get_status() const { return froid.get_status()+ " | "+ chaud.get_status();} //void set_mode(Mode m) {mode= m;}
std::atomic<Mode> mode{OFF}; // => #include <atomic> ??
merci
Salut,
std::atomic, c'était dans l'éventualité d'avoir à protéger la variable d'accès concurrents, notamment avec les "threads".
Pour te donner une image, si tu vas dans un restaurant qui n'applique pas l'atomicité, en tant que client, tu risques de recevoir une assiette vide ou insuffisamment garnie (y compris dans les restaurants chiques où le garnissage est inversement proportionné à l'addition).
Dans le code, ça revient à écrire std::atomic<Mode> mode au lieu de Mode mode. Le compilateur s'occupe du reste. Bien sûr, il faut un #include <atomic> en amont.
Pour ce qui est du reste, sauf le set_mode(), ce n'était que des illustrations de mécanismes sous-jacents. Car dans les faits, rien n'oblige à avoir ce get_status() en particulier, mais juste quelque part, à rendre compte de l'état du système. Par exemple, en activant ou non un symbole sur un afficheur. De même pour get_mode(), si le système de chauffage est désactivé, les demandes de production de chaleur par le thermostat seront juste ignorées. En fait, les bouts de codes faisaient juste état de possibles orientations, sauf à être imposées par l'écosystème, bien entendu.
je vais donner un exemple simpliste et abordable (j'espère) et sans introduire de nouvelles notions qui risquent de causer des blocages :
Comme écrit en préambule, c'est loin d'être un code compact et sophistiqué (avec même une erreur (ou plutôt contrainte) de conception), mais plutôt verbeux et, ben j'ai finalement rebroussé chemin pour le rendre incomplet.. Du coup, pour qu'il fonctionne, il y a des modifications qui sont nécessaires. C'est laissé comme "exercice" compte tenu de la nature du projet, histoire de quand même faire un point.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 class Froid { private: void disable() {enabled= false;} void display_status() { if (enabled) {TRACE("Froid: ENABLED\n");} else {TRACE("Froid: DISABLED\n");} } bool enabled{false}; }; enum Mode {OFF, CHAUFFAGE}; class PAC { // Pompe_A_Chaleur public: void set_mode(Mode m) { mode= m; switch (m) { case OFF: disable_all(); case CLIM: enable_froid(); break; } display_status(); } Mode get_mode() {return mode;} // en réponse à la question précédente, si besoin d'un get_mode() private: Chaud chaud{}; void enable_chaud() {froid.disable(); chaud.enable();} Mode mode{OFF}; }; int main() { PAC pax; TRACE("Setting CLIM mode...\n"); pac.select_mode(CLIM); TRACE("Setting chauffage mode...\n"); pac.select_mode(chauffage); }
bonjour , donc j'ai fais quelque chose comme ce qui suit
comment puis je incorporer le chrono pour remplacer la boucle while ,
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113 #include <chrono> #include "Trace.h" #include "ds18b20.h" #include "Thermostats.h" class Froid { public: void disable_froid() {enabledFroid = false;} void enable_froid() {enabledFroid = true;} void display_status_froid() { if (enabledFroid) {TRACE("Froid: ENABLED\n");} else {TRACE("Froid: DISABLED\n");} } private: bool enabledFroid {false}; }; class Chaud { public: void disable_chaud() {enabledChaud = false;} void enable_chaud() {enabledChaud = true;} void display_status_chaud() { if (enabledChaud) {TRACE("Chauffage: ENABLED\n");} else {TRACE("Chauffage: DISABLED\n");} } private: bool enabledChaud {false}; }; enum Mode {OFF, CHAUFFAGE, FROID, AUTO}; class PAC { // Pompe_A_Chaleur public: void set_mode(Mode m) { mode = m; switch (m) { case OFF: TRACE("OFF\n"); disable_all(); break; case FROID: TRACE("FROID\n"); froid.enable_froid(); froid.display_status_froid(); break; case CHAUFFAGE: TRACE("CHAUFFAGE\n"); chaud.display_status_chaud(); break; case AUTO: TRACE("AUTO\n"); if (read_sensor_outside() <= 13.5) {m = CHAUFFAGE;} else {m = FROID;} break; } } void display_temperature() {TRACE("sensor outside : %2.2f\n", read_sensor_outside());} double read_sensor_outside() {return sensorOutside.get_tempExt();} bool read_switch_room() {TRACE("thermostat is: %s", switchRoom.get_etatThermostat() ? "true\n" : "false\n"); return switchRoom.get_etatThermostat();} Mode get_mode() {return mode;} // en réponse à la question précédente, si besoin d'un get_mode() private: Chaud chaud{}; Froid froid{}; DS18B20 sensorOutside{}; Thermostat switchRoom{}; Mode mode{OFF}; void disable_all() {chaud.disable_chaud(); froid.disable_froid();} }; int main() { PAC pac; pac.display_temperature(); if (pac.read_switch_room()) { if (pac.read_sensor_outside() <= 13.5) {TRACE("Setting chauffage mode...\n"); pac.set_mode(CHAUFFAGE);} else {TRACE("Setting refroidissement mode...\n"); pac.set_mode(FROID);} } else {TRACE("Setting pac mode...\n"); pac.set_mode(OFF);} }
j'essais plein de chose avec les marqueur du temp mais je n'y arrive pas .
Salut,
C'est dommage, tu es parti trop loin et avec précipitation. J'aurais préféré une réponse plus tôt, où tu te serais contenté, comme demandé, de faire fonctionner le code précédent. C'est-à dire que dans PAC, il y a les fonctions enable_chaud() {froid.disable(); chaud.enable();}et enable_froid() {chaud.disable(); froid.enable();} permettant de garantir leur exclusion mutuelle (en plus, elles étaient écrites dans un code précédent). L'étape suivante était de restreindre les interfaces de chaud et froid pour éviter le genre de manipulation hasardeuse que tu as faites dans ton switch. Et maintenant il est question de chrono.
Le chrono, c'était pour les temporisations. Quelle est ta question exactement ?
je suis d'accord je me suis éparpillé ,
donc j'avait reussi a faire fonctionner le code du depart
et en sortie :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91 #include <thread> #include "Trace.h" #include "ds18b20.h" class Froid { public: void disable() {enabled = false;} void enable() {enabled = true;} void display_status() { if (enabled) {TRACE("Froid: ENABLED\n");} else {TRACE("Froid: DISABLED\n");} } private: bool enabled {false}; }; class Chaud { public: void disable() {enabled = false;} void enable() {enabled = true;} private: void display_status() { if (enabled) {TRACE("Chauffage: ENABLED\n");} else {TRACE("Chauffage: DISABLED\n");} } bool enabled {false}; }; enum Mode {OFF, CHAUFFAGE, FROID, AUTO}; class PAC { // Pompe_A_Chaleur public: void set_mode(Mode m) { mode = m; switch (m) { case OFF: disable_all(); case FROID: enable_froid(); break; case CHAUFFAGE: enable_chaud(); break; } froid.display_status(); } Mode get_mode() {return mode;} // en réponse à la question précédente, si besoin d'un get_mode() void display_temperature() {TRACE("sensor outside : %2.2f\n", sensorOutside.get_tempExt());} private: Chaud chaud{}; Froid froid{}; DS18B20 sensorOutside{}; Mode mode{OFF}; void enable_chaud() {froid.disable(); chaud.enable();} void enable_froid() {chaud.disable(); froid.enable();} void disable_all() {froid.disable(); chaud.disable();} }; int main() { PAC pac; TRACE("Setting froid mode...\n"); pac.set_mode(FROID); TRACE("Setting chauffage mode...\n"); pac.set_mode(CHAUFFAGE); }
Setting froid mode...
Froid: ENABLED
Chauffage: DISABLED
Setting chauffage mode...
Froid: DISABLED
Chauffage: ENABLED
pour les tempos c'est bon j'ai compris comment il fonctionne
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 while(1) { std::this_thread::sleep_for(std::chrono::seconds{2}); pac.display_temperature(); // s'affiche toute les 2 secondes. }
Salut,
À dire vrai, ça avait déjà commencé il y a 15 jours avec CMake. Des jours définitivement perdus, puisque pour un temps, je ne serais probablement plus en mesure de participer à la discussion, donc une contribution en moins.
Pour ce qui est du reste, ta sortie ne correspond pas au code présenté, peut-être des artefacts de rééditions.
Aussi, dans la classe PAC, il manque des break dans le switch, certainement déjà signalés par compilateur. Si ce n'est pas le cas, il faut voir les options d'alertes -Wall -Wextra. Il manque aussi la fonction void display_statut(){froid.display_status(); chaud.display_status();}, qu'il faut appeler en fin du switch.
Le nom mode FROID, je ne sais pas ce qu'en pensent mes camarades, mais moi, ça m'évoque l'HIVER, le GRAND_FROID, c'est-à-dire la nécessité d'augmenter la puissance du chauffage.
Et si tu veux un mode AUTO, schématiquement, ça pourrait se traduire par un enable_auto(){disable_all();}, chaud ou froid sera activé à la demande du thermostat. Conf le message de Cléon, l'histoire du thermostat qui parle à la chaudière. Je n'avais pas cité cette conversation juste pour le fun, mais parce qu'il était possible d'y déceler un "patterrn", donc très à propos pour cette discussion.
c'est une erreur de ma part pour le break ;
apres les thermostats reglable oui parle a mon system (les thermostats reste que des entrées pour mon cas) NC ou NO (0 ou 5vdc) qu'il renvoi juste un bool,
le froid n'existe pas !!! c'est un manque de chaleur, clim c'est climatiseur ne fait pas forcement du chaud mais que du froid , pac c'est pompe a chaleur (convertible ou pas ) ne fait pas forcement du froid (pac dans un seche linge il sert qu'as faire du chaud). bref , mois c'est un groupe (pac aire/aire convertible qui fonctionne avec un vanne 4 voie (sur la partie frigorifique qui inverse le circuit pour que quand il fais froid dehors j'ai du chauffage a l'interieur et vis versa ), le tous est controler par des thermostat radio dans chaque piece pour ouvrir le volet de la piece qui demande du froid ou du chaud en fonction de la saison .
automatique est le fais que l'appareil n'as plus besoin de manipulation elle le gere toute seule (entre les saisons ete et hiver) a la demande de l'utilisateur .
le mode froid c'est que nous somme en été et le mode chaud est que nous somme en hiver.
tous les modes(auto, froid, chaud) sont gerer par les thermostats et le mode chaud ou froid est gerer par la temperature moyenne annuel de ma region (14°C)
l'automatique (entre les saisons hiver ou été) gere la temperature ambiante de la maison (23°C si en dessous de 21°C passe en mode chauffage ou 25°C passe en mode froid)
desole je me suis mal fais comprendre !
Cela fait partie des nombreuses raisons qui m’ont poussée à écrire que, même si le système sous-jacent était une bouillotte, que ça n'avait aucune importance.
Mais les actions demandées, là ça doit être clair. Quand on parle de chauffage/clim c'est clair pour tout le monde, été/hiver, c'est clair pour tout le monde, chauffage/froid, il n'y a plus personne. Des invités chez toi, s'ils savent qu'il peuvent avoir plus de fraicheur, ils te demanderont de mettre la clim s'il te plait. Même si tu n’as pas de climatiseur, la demande est claire. Bon, au pire, tu pourras leur donner un éventail. Et si je ne me trompe pas, @bacelar t'avait déjà rappelé l'importance des noms.
Pour le mode AUTO, même si ton thermostat ne sait faire que du on/off, ce n’est pas un problème non plus. Ta PAC activera ce qu'il convient au moment où son entrée sera signalée, et en fonction des conditions fixées.
merci , pour refroidissement je vais mettre cooling et heating pour chauffage , je pense que se serais plus clair comme cela.
pour ce bout de code si dessu,
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 void run_machine(const PAC& pac) { //may be (later) PAC member function: void PAC::run_machine() { // or void run_machine(const Model& model) { //Trace only when the state changes //something like: auto trace_condition{ __LINE__ }; // <= (reminiscence) TRACE_CONDITION_INIT(optional_condition_type(BASIC | TREE), opt_name, opt_condition); while (pac.get_mode() != SHUTDOWN) { //or (model.mode != SHUTDOWN) // or ( ! must_exit()) std::this_thread::sleep_for(std::chrono::seconds(1)|1s); //prevent high CPU load if (pac.termostat.wath_requested() == Request::heating) { if (pac.get_mode() == CHAUFFAGE) { //auto debug_mode_enabled= DEBUG_MODE_ENABLED & (__LINE__ != trace_condition); trace_condition= __LINE__; // <= TRACE_CONDITION_NOTRACE_ON_MATCH(..); _ON_MISMATCH(...); TRACE("Production et acheminement de la chaleur en cours...\n"); TRACE("Utilisation de l'algo %s...\n", (pac|termostat).get_sub_mode_chauffage_name()); } else { //TRACE_CONDITION_NOTRACE_ON_MATCH(..) TRACE("Production de chaleur requise par le thermostat, mais interdite par le PAC.\n"); } // .... } turn_off_hardward(); }
comment fonctionne dans cette fonction la class en reference ?
merci .
Attention, le jargon technique est toujours plus précis que les ambiguïtés du quidam.
Donc les noms sont importants mais quand ils sont précis.
L'interface utilisateur ne doit pas être jargonneux mais c'est pour ça qu'on a tendance à concevoir l'interface à part, plus tard, faisant le bon entre un outil utilisable par un "rookie" mais facilement maintenable par un professionnel du domaine.
Je ne suis pas sûr que le multithreading soit la manière de faire la plus simple pour un débutant.
Vous êtes sûr ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part std::chrono::seconds(1)|1s
Je ne suis pas sûr que vous avez pris le temps de faire des POC intermédiaires.
Qu'entendez-vous par "class en reference" ?cette fonction la class en reference ?
l'objet pas en paramètre de la fonction, qui est passé en référence constante ?
Salut ,
coucou toi,
Oui, il cite un pseudocode d'un de mes messages (#62). Il ne l'a pas balisé comme il se doit, et hors contexte, effectivement, ça prête à confusion. Dans cette expression, j'ai formalisé le "or", alors qu'un peu plus loin, il est en toutes lettres.
Ben, sans, ça reviendrait un peu à coder l'équivalent d'une boucle de jeu. Avec l'interface graphique, la gestion des timings, la nécessité d'un watchdog, c'est carrément hors de sa portée. Un projet comme ça devrait même être scindé en plusieurs processus, notamment pour des modifs de sécurité, mais avec les IPC, ce sera pareil. Il pourrait aussi se reposer sur les rappels et minuteries de l'OS, de Qt, mais je vois ça comme des entraves. Donc c'est un peu ce qui a motivé la proposition MVC+Threads détaillée dans le même précédent message (#62). Je te laisse voir...
IHM + multithread, c'est le début des emmerdes.
On peut très bien faire un calendrier des évènements "planifiés" et ne garder qu'une pompe à message.
Pour la sécurité, des watchdog dans des programmes indépendants est bien plus "safe".
salut a tous ,
donc j'ai fait ce bout de code , je pense qu'il ya beaucoup de chose a voir ,
j'ai supposé que tous ce qui est display est eventuellement pour l'interface graphique ?
je pense aussi qu'il faut que je recrée soit des nouvelle enum pour les differents etats de chaque objet (froid, chaud, auto et maintenance)
le plus difficile a mon avis c'est les temporisation de chaque etat de ma machine en fonction du mode que je suis . meme ci deja la c'est pas simple pour moi .
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147 #include <thread> #include <iostream> #include <string> #include "Trace.h" #include "ds18b20.h" #include "Thermostats.h" #include "Relay.h" class Cooling { public: void disable() {enabled = false;} void enable() {enabled = true;} void display_status() { if (enabled) {TRACE("Froid: ENABLED\n");} else {TRACE("Froid: DISABLED\n");} } private: bool enabled {false}; }; class Heating { public: void disable() {enabled = false;} void enable() {enabled = true;} void display_status() { if (enabled) {TRACE("Chauffage: ENABLED\n");} else {TRACE("Chauffage: DISABLED\n");} } private: bool enabled {false}; }; class Automatic { public: void disable() {enabled = false;} void enable() {enabled = true;} void display_status() { if (enabled) {TRACE("Automatique: ENABLED\n");} else {TRACE("Automatique: DISABLED\n");} } private: bool enabled {false}; }; enum Mode {OFF, HEATING, COOLING, AUTO, MAINTENANCE}; class PAC { // Pompe_A_Chaleur public: void run_pac() { while (1) { std::this_thread::sleep_for(std::chrono::seconds{2}); if (read_thermostat_room()) { if (read_sensorOutside() <= 13.5) { TRACE("Setting chauffage mode...\n"); set_mode(HEATING); } else { TRACE("Setting froid mode...\n"); set_mode(COOLING); } } else { TRACE("Setting off mode ...\n"); set_mode(OFF); } } } private: Heating chaud {}; Cooling froid {}; Automatic automatique {}; DS18B20 sensorOutside {}; Thermostat thermostatRoom {}; Relay orderRelay {}; Mode mode{OFF}; void set_mode(Mode m) { mode = m; switch (m) { case OFF: disable_all(); break; case COOLING: enable_froid(); break; case HEATING: enable_chaud(); break; case AUTO: enable_auto(); break; case MAINTENANCE: //enable_maintenance(); break; } display_status(); } Mode get_mode() {return mode;} // en réponse à la question précédente, si besoin d'un get_mode() double read_sensorOutside() {return sensorOutside.get_tempExt();} void display_outdoor_temperature() {TRACE("sensor outside : %2.2f\n", sensorOutside.get_tempExt());} bool read_thermostat_room() {TRACE("thermostat is: %s", thermostatRoom.get_etatThermostat() ? "true\n" : "false\n"); return thermostatRoom.get_etatThermostat();} void enable_chaud() {automatique.disable(); froid.disable(); chaud.enable(); orderRelay.highRelayEteHiver();} void enable_froid() {automatique.disable(); chaud.disable(); froid.enable(); orderRelay.lowRelayEteHiver();} void enable_auto() {froid.disable(); chaud.disable(); automatique.enable();} void disable_all() {froid.disable(); chaud.disable(); automatique.disable(); orderRelay.lowTousRelay();} void display_status() {display_outdoor_temperature(); froid.display_status(); chaud.display_status(); automatique.display_status();} }; int main() { PAC pac; pac.run_pac(); }
Ok, maintenant essayez de sortir la boucle de "run_pac" à l'extérieur.
(Ce qui est en rouge est fonction du framework/librairie graphique que vous souhaitez utiliser)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 void run_pac() { if (read_thermostat_room()) { ... } ... } ... int main() { PAC pac; .... SetTimer(std::chrono::seconds{2}, pac::run_pac); .... do{ .... PompeAMessage(); .... }while(!Finir()); }
Ainsi, le code de la classe PAC n'est pas fonction du "framework/librairie graphique" et ne bloque pas toute la machinerie.
je suis desole je vois pas du tous comment faire? merci
Partager