Bonsoir @chris99977
Un énorme merci ! Grâce à toi je parviens maintenant aussi à piloter la consigne, les explications sont parfaites, merci aussi à tout ceux qui ont contribué à ce projet !
Pour le bug du compresseur qui visuellement ne passe pas en stop si target < à Tin ou Tout et autre, je vais tester ça demain.
Je confirme qu’avec la gestion par « registres » (Des tableaux), pas de soucis de modification du mode lors de la modification de la consigne.
Je pense que c’est ce qu’il y a de plus simple, il y a un tableau par adresse (A ce propos, les adresses 07 D1 et 04 43 se chevauchent du au nombre de datas, mais les datas ne sont pas du tout les même à ce niveau, ce n’est donc pas du Modbus classiquement implémenté, pas d’accès mémoire direct, il y a du traitement entre deux), et j’ai aussi multiplié cela par deux pour les essais, un jeu de tableaux de recopie de ce qu’on voit passer vers et depuis l’IHM, et nos tableaux, identiques, cela donne donc les tableaux suivants (Je dois mettre ça au propre) :
uint8_t holding_register_broadcast[256]; //Adresse 07 D1 (Unit state)
uint8_t holding_register_parametres_ihm[256]; //Adresse 03 E9 (Paramètres, Mode)
uint8_t holding_register_action_ihm[256]; //Adresse 0B B9 (Heure IHM, Action)
uint8_t holding_register_0443_ihm[256]; //Adresse 04 43 (?)
uint8_t holding_register_parametres_gateway[256]; //Adresse 03 E9 (Paramètres, Mode)
uint8_t holding_register_action_gateway[256]; //Adresse 0B B9 (Heure module WiFi, Action)
uint8_t holding_register_0443_gateway[256]; //Adresse 04 43 (?)
Lorsqu’on reçoit les datas correspondantes (Broadcast, ou écoute des échanges avec l’IHM), on les recopie dans le bon tableau, exemple :
else if (msg[2] == 0x04 and msg[3] == 0x43) { //Paramètres
PUB("WARMPOOL/D00", String(XtoFloat(27, 28)).c_str()); //Aussi nommé D01 sur IHM
PUB("WARMPOOL/D01", String(XtoFloat(29, 30)).c_str());
PUB("WARMPOOL/D02", String(XtoFloat(31, 32)).c_str());
PUB("WARMPOOL/D03", String(XtoInt(33, 34)).c_str());
debugW("Ecriture Broadcast 0443 Parametres");
for (uint8_t i = 0; i < msg[6]; i++) { //msg[6] = nombre d'octets de datas
holding_register_0443_gateway[i] = holding_register_0443_ihm[i] = msg[i + 7];
}
}
Lorsqu’on fait une action MQTT, on écris dans la bonne case du tableau adéquat pour y écrire soit la consigne, soit le mode, ainsi que la demande de prise en charge par le contrôleur (0x04 ou 0x10, encore merci), exemple :
else if (topic.startsWith("WARMPOOL/set/")) {
if (topic.endsWith("target")) {
m_target = payload.toFloat() * 10;
holding_register_parametres_gateway[24] = highByte(m_target);
holding_register_parametres_gateway[25] = lowByte(m_target);
holding_register_0443_gateway[94] = highByte(m_target);
holding_register_0443_gateway[95] = lowByte(m_target);
holding_register_action_gateway[21] = 0x10;
state.dirty = true;
} else if (topic.endsWith("mode")) {
if (payload.equals("OFF")) m_mode = 0x00;
else if (payload.equals("Heat")) m_mode = 0x84;
else if (payload.equals("Cool")) m_mode = 0x81;
else if (payload.equals("Auto")) m_mode = 0x88;
else if (payload.equals("ON")) m_mode = 0x01;
holding_register_parametres_gateway[21] = m_mode;
holding_register_parametres_gateway[27] = m_mode;
holding_register_action_gateway[21] = 0x04;
state.sub = 0x02;
state.dirty = true;
}
}
Ensuite, le contrôleur nous envoi donc une requête de lecture, nous n’avons qu’à reconstruire l’entête en fonction de la demande, et transmettre les datas du tableau:
else if (msg[0] == 0x02) { //La PAC communique avec le module WiFi
if (msg[1] == 0x03) { //La PAC lis depuis le module WiFi
uint8_t RPLY[(XtoInt(4, 5) * 2) + 3]; //On répond une trame avec le nombre de mots demandées dans la requête de lecture
//Préparation entête
RPLY[0] = msg[0]; //Adresse équipement qui a reçu la requête et qui répond (Nous, le même que la requête)
RPLY[1] = msg[1]; //Code fonction (Le même que la requête)
RPLY[2] = XtoInt(4, 5) * 2; //Nombre d'octets de datas envoyés (Le nombre de mots demandés * 2)
if (msg[2] == 0x03 and msg[3] == 0xE9) { //La PAC lis depuis le module WiFi à l'adresse 03 E9
TypeMessage = 5;
if (holding_register_parametres_gateway[0] != 0) { //On a les informations nécessaires à l'envoi de la trame
//Préparation trame (Lecture trame de base)
for (uint8_t i = 0; i < RPLY[2]; i++) {
RPLY[i + 3] = holding_register_parametres_gateway[i];
}
debugW("Reponse x02 (Parametres)");
sendmsg(RPLY, sizeof(RPLY));
}
else {
debugE("Buffer holding_register_parametres_gateway vide, patientez le temps de decouvrir la trame echangee avec l'IHM.");
}
De cette manière, la consigne et le mode seront toujours à jour: Pas de soucis de repassage au mode d’avant lorsqu’on change la consigne par exemple, en plus on a une trame identique a ce qu’aurait envoyé l’IHM, sans avoir a modifier le programme.
Voici mon programme, brut de décoffrage de mes essais d’aujourd’hui … J’ai encore du boulot de nettoyage et optimisation, il ne ressemble pas beaucoup au code d’origine mais l’idée est là :
/!\ Attention, suite à mes essais j’ai un bug avec ma PAC, la consigne semble figée à une température basse, même si au niveau de l’affichage écran je peux la changer (En mode chaud, le compresseur ne démarre pas, en mode froid il démarre et refroidis l’eau alors que la consigne est au dessus, et en mode auto idem) J’ai donc retiré le code au cas ou le temps de corriger cela /!\