Page 47 sur 50

Re: [Tuto] Régulation d'une chaudière Frisquet ECO radio System

Publié : 12 mars 2022, 11:40
par o0larry0o
Bonjour à tous,
Je suis désolé, de poster ce message que je sais être un peu Hors sujet, néanmoins, c'est le thread le plus complet que j'ai jamais vu en Francais sur les chaudières frisquet !!!

Et vous semblez avoir des compétences incroyables, et ma question est très très simple :)

Je possède une Frisquet Hydromotrix évolution avec Eco Radio System.

Je souhaiterais y ajouter un boitier domotique Wifi, de Type Shelly 1 avec contact sec.

L'objectif:
conserver la régulation Eco Radio Système qui dispose d'une programmation avec plages horaires et qui me convient très bien
pouvoir forcer (bypass des instructions Eco Radio) la coupure de la chaudière si je ne suis pas là.

Par exemple,
- de 19h a 20h période nuit avec température minimale
- 20h 21h température de confort à 20°C, si je ne suis pas la je commande à la chaudière de ne pas démarrer
- 21h 22h je rentre chez moi, je commande à la chaudière de repasser en mode standard, le fonctionnement normal Eco Radio reprend selon la programmation définie

Est ce que je contact sec pourrait répondre à ce besoin ?

Je vous remercie beaucoup pour votre aide.
(je vous souhaitez que je supprime mon post pas de souci, mais je veux bien un coup de main en MP :) )

Re: [Tuto] Régulation d'une chaudière Frisquet ECO radio System

Publié : 12 mars 2022, 14:16
par christopheHD
o0larry0o a écrit : 12 mars 2022, 11:40 Est ce que je contact sec pourrait répondre à ce besoin ?
Non, le contact sec permet uniquement de forcer la chaudière à chauffer l'eau de chauffage.

Re: [Tuto] Régulation d'une chaudière Frisquet ECO radio System

Publié : 12 mars 2022, 16:17
par o0larry0o
tristesse infinie .... ^^

Donc je vais lire un peu le thread pour voir si je pourrais implementer ca chez moi.
Mais je n'ai aucune connaissance en domotique aussi avancée :/

Merci

Re: [Tuto] Régulation d'une chaudière Frisquet ECO radio System

Publié : 12 mars 2022, 17:32
par o0larry0o
Re bonjour, 1h15 de lecture plus tard depuis la page 28 :)

Je pense avoir bien compris les choses et les différentes solutions.
Je ne suis pas manchot en informatique et je pense être dans le même cas que @ParkerLewis

Une chose que je ne suis pas certain d'avoir compris.
est il possible de continuer à programmer une température d'ambiance ? si oui comment faites vous pour mesurer la température d'ambiance et l'utiliser pour la programmation des commandes ?

ou faut il obligatoirement passer en commande de la température d'eau, et donc par extension en loi d'eau ?

Dans tous les cas, je pense partir sur la solution RFLink, qui me semble bien plus pratique étant non invasive, et permet facilement de rebasculer sur la télécommande Frisquet au cas ou.

Je suis au très curieux de voir ou vous en êtes @ParkerLewis et @benoit.divers.91

Merci pour le boulot, c'est fantastique :)

Re: [Tuto] Régulation d'une chaudière Frisquet ECO radio System

Publié : 14 mars 2022, 13:43
par christopheHD
o0larry0o a écrit : 12 mars 2022, 17:32 est il possible de continuer à programmer une température d'ambiance ? si oui comment faites vous pour mesurer la température d'ambiance et l'utiliser pour la programmation des commandes ?

ou faut il obligatoirement passer en commande de la température d'eau, et donc par extension en loi d'eau ?
Seul le thermostat connait la température d'ambiance, la chaudière ne connait que la température d'eau, donc oui il faut passer obligatoirement par une loi d'eau ou un algorithme PID.

Re: [Tuto] Régulation d'une chaudière Frisquet ECO radio System

Publié : 15 mars 2022, 22:48
par ParkerLewis
ngrataloup a écrit : 11 mars 2022, 12:33 Bonjour,

J'essaye de mettre en service un module RFlink sur la base des travaux de @christopheHD
mais je bute sur le nouveau transceiver Aurel fournit par Nodoshop. J'ai réussi la recevoir les trames pour connaitre l'ID de ma chaudière, mais impossible de le faire fonctionner en emission
@ParkerLewis et @benoit.divers.91, avez vous réussi à gérer l'émission des consignes vers la chaudière suite à vos derniers messages ?



Norbert
Hello @ngrataloup,

Je n'ai pas eu le temps de me pencher sur l'émission depuis. Tu peux voir sur ce post les réflexions que j'avais eues pour la réception, mais sans avoir eu le temps de les tester. Le post de benoit juste en-dessous apportait la solution, qui semblait être assez cohérente de ce que j'avais identifié pour les pins. Donc avec un raisonnement similaire pour l'émission (aller regarder les manuels) ça evrait être dans les bonnes eaux aussi...

Si tu arrives à faire marcher je suis preneur.

Re: [Tuto] Régulation d'une chaudière Frisquet ECO radio System

Publié : 05 avr. 2022, 00:40
par insosama
bonjour

premier message sur le fofo.
ce topic est impressionnant. je le suis depuis longtemps, mais je me suis décidé à le mettre en oeuvre que récement.
j'ai acheté un RFlink tout fait, en 334.42Mhz, chez nodo, parce qu'en travaux, j'ai eue la flemme de prendre le risque de perdre des morceau et pas gérer la soudure.

quel n'a pas été ma déception que ca ne marche pas. je suis allé sur le git de Christophe HD, j'ai DL les deux fichier qui pourtant sont a priori dédié au nodo, et patatra;
me voila donc a parcourir les derniers topic que j'avais loupé.

j'ai découvert le correctif, j'ai un peu "luté" pour le mettre en oeuvre.

pour que je contribue, voila les deux notes pour la postérité :
d'abord, le fichier =>

Code : Tout sélectionner

#define TRANSCEIVER_RX_PIN      19    // Set the pin that receives data from your 433.42 Mhz Receiver
#define TRANSCEIVER_MODE_PIN    15    // Aurel transceivers have a pin that let the hardware switch to RX and TX mode
#define TRANSCEIVER_ENABLE_PIN  22    // Aurel transceivers have a pin that must be set to HIGH to enable the transmitter

// DO NOT CHANGE THESE SETTINGS BELOW
#define TRANSCEIVER_TX HIGH
#define TRANSCEIVER_RX  LOW

volatile long duration = 0;
volatile long prev_time = 0;
volatile boolean data_dispo = false;
byte input = TRANSCEIVER_RX_PIN;
String trame[3];
byte message = 0;
byte start = true;
byte intro = 0;
String prefixe = "1100";
 
void setup() {
  Serial.begin(115200);
  // set the Aurel transceiver to RX mode
  pinMode(TRANSCEIVER_MODE_PIN, OUTPUT);
  digitalWrite(TRANSCEIVER_MODE_PIN, TRANSCEIVER_RX);

  // enable Aurel transmitter
  pinMode(TRANSCEIVER_ENABLE_PIN, OUTPUT);
  digitalWrite(TRANSCEIVER_ENABLE_PIN, HIGH);

  delay(500);

  // assign an interrupt on pin x on state change
  pinMode(TRANSCEIVER_RX_PIN, INPUT);
  attachInterrupt(digitalPinToInterrupt(input), declenche, CHANGE);
  
  pinMode (LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
  Serial.print("Hello world");
}
 
void loop() {
  if (data_dispo == true) {
    int bit_state = digitalRead(input);
    if ((duration > 700) && (duration < 950)) { // pulse off court
      trame[message] = trame[message] + !bit_state;
    } else if ((duration > 1400) && (duration < 1950)) { // pulse off long
      // verifie qu'on commence avec un pulse long à 1
      if ((start == true) && (!bit_state == HIGH)) {
        trame[message] = trame[message] + !bit_state + !bit_state;
        start = false;
      } else if (start == false) {
        trame[message] = trame[message] + !bit_state + !bit_state;
      }
    } else {
      start = true; // debut d'une nouvelle trame
      if (trame[message].length() > 200) {
        message++;
        if (message > 2) {
          for (message = 0; message < 3; message++) {
            for (int x = 0; x <= 50; x=x+4) {
              if (trame[message].substring(x,x+4).compareTo(prefixe) == 0) {
                intro++;
              } else {
                break;
              }
            }
            if (intro > 6 ) {
              digitalWrite(LED_BUILTIN, HIGH);
              // décodage des bits de la trame: 00=0, 11=0, 10=1, 01=1
              String sortie = "";
              for (int x = (intro*4); x <= trame[message].length(); x=x+2) {
                if ((trame[message].substring(x,x+2) == "00") or (trame[message].substring(x,x+2) == "11")) {
                  sortie = sortie + "0";
                } else {
                  sortie = sortie + "1";
                }
              }
              String sortie_without_bitstuff = remove_bitstuff(sortie);
              sortie = sortie_without_bitstuff;
              String sortie_hex = convert_binary_string_to_hex_string(sortie);
              Serial.print("Trame reçue :");
              Serial.println(sortie_hex);

              // repartition en bytes
              byte id1 = convert(sortie.substring(0,8)); // byte 3
              byte id2 = convert(sortie.substring(8,16)); // byte 4
              byte id3 = convert(sortie.substring(16,24)); // byte 5
              byte num = convert(sortie.substring(48,56)); // byte 9 (repeat)
              byte prechauff = convert(sortie.substring(56,64)); // byte 10 (pre-heated) 0=Reduit, 3=Confort, 4=Hors gel
              byte chauffage = convert(sortie.substring(64,72)); // Heating
              byte battery = convert(sortie.substring(72,80)); // Battery
              Serial.print("Message #");
              Serial.println(num);
              Serial.print("ID: ");
              Serial.print(id1, HEX);
              Serial.print("-");
              Serial.print(id2, HEX);
              Serial.print("-");
              Serial.println(id3, HEX);
              Serial.print("Mode : ");
              prechauff &= 0x0F;
              switch (prechauff) {
                case 0:
                  Serial.println("Réduit");
                  break;
                case 3:
                  Serial.println("Confort");
                  break;
                case 4:
                  Serial.println("Hors gel");
                  break;
                default:
                  Serial.print("Inconnu (");
                  Serial.print(prechauff);
                  Serial.println(")");
              } 
              Serial.print("Température eau : ");
              Serial.println(chauffage);
              Serial.print("Batterie : ");
              if (battery > 0)
                Serial.println("LOW");
              else
                Serial.println("OK");
              if (num > 1)
                Serial.println("##########");
              else
                Serial.println("----------");
              intro = 0;
              digitalWrite(LED_BUILTIN, LOW);
            }
          }  
          trame[0] = "";
          trame[1] = "";
          trame[2] = "";
          message = 0;
        }
      } else {
        // Re-initialise la trame s'il n'y avait pas de données juste avant      
        if ((message == 0) || (trame[message-1].length() < 200)) { 
          trame[0] = "";
          trame[1] = "";
          trame[2] = "";
          message = 0;
        }
      }
    }
    data_dispo = false;
  }
}

void declenche() {
  duration = micros()-prev_time;
  prev_time = micros();
  data_dispo = true;
}

byte convert(String entree) {
  byte result = 0;
  for (int f = 0; f <= 7 ; f++) {
    if (entree.substring(f,f+1) == "1") bitSet(result, f);
  }
return result;
}

String convert_binary_string_to_hex_string(String data) {
  String sortie = "";
  for (int x = 0; x < (data.length()/8);x++) {
    byte hex = 0;
    for (int f = 0; f <= 7 ; f++) {
      if (data.substring((x*8)+f,(x*8)+f+1) == "1")
        bitSet(hex, f);
    }
    if (hex <= 0x0F)
      sortie += "0";
    sortie += String(hex, HEX);
  }
  sortie.toUpperCase();
  return sortie;
}

String remove_bitstuff(String data) {
  // The protocol uses bit-stuffing => remove 0 bit after five consecutive 1 bits
  // Also, each byte is represented with least significant bit first -> swap them!
  String sortie = "";
  int ones = 0;
  for (uint16_t k = 0; k < data.length(); k++) {
    if (data[k] == '1') {
      sortie += "1";
      ones++;
    } else {
      if (ones != 5) // Ignore a 0 bit after five consecutive 1 bits:
        sortie += "0";
      ones = 0;
    }
  }
  return sortie;
}
comme le stipule l'aide, ouvrez ensuite un terminal com.
vous devriez voir un "hello word" qui s'affiche. si ce n'est pas le cas et / ou qu'il apparait avec une forme zarb, pas de panique !
le fait est aussi que la vitesse a changé. en bauds, vous devrez mettre : 115200 <- ca, c'est la seconde information ^^

mettez le thermostat en "jour", puis changez la température, puis remettez vous en auto.
puis ATTENDEZ QUELQUES SECONDES.
et la, BINGO, ca marche.

ensuite, on attaque le transeiver; ici, je peu fournir deja quelques indications, mais comme je n'ai pas réussi a faire marcher le tout, peut etre que ces indications ne sont pas les bonnes, alors soyez prudents.

https://github.com/ChristopheHD/frisque ... ceiver.ino

les broches 19,15,22 me laissent penser que ca été corrigé ?
puisque le début :

Code : Tout sélectionner

#define TRANSCEIVER_RX_PIN      19    // Set the pin that receives data from your 433.42 Mhz Receiver
#define TRANSCEIVER_MODE_PIN    15    // Aurel transceivers have a pin that let the hardware switch to RX and TX mode
#define TRANSCEIVER_ENABLE_PIN  22    // Aurel transceivers have a pin that must be set to HIGH to enable the transmitter
#define TRANSCEIVER_TX HIGH
#define TRANSCEIVER_RX  LOW
ressemble comme deux goutte d'eau a la version modifié du fichier de reception corrigé que j'ai partagé plus haut :

Code : Tout sélectionner

#define TRANSCEIVER_RX_PIN      19    // Set the pin that receives data from your 433.42 Mhz Receiver
#define TRANSCEIVER_MODE_PIN    15    // Aurel transceivers have a pin that let the hardware switch to RX and TX mode
#define TRANSCEIVER_ENABLE_PIN  22    // Aurel transceivers have a pin that must be set to HIGH to enable the transmitter
// DO NOT CHANGE THESE SETTINGS BELOW
#define TRANSCEIVER_TX HIGH
#define TRANSCEIVER_RX  LOW
je vois que le programme a été modifié il y a quelques semaines, alors peut etre que c'est bon ?

et la, c'est galère sur galère.
déjà, il y a un

Code : Tout sélectionner

#include <SerialTerminal.hpp>
aucune aide en parle.
apres recherche, j'ai trouvé la librairie en question :
https://github.com/miko007/SerialTermin ... rminal.hpp

il faut enregistrer le fichier "SerialTerminal.hpp" (je pense que la casse (majuscule) est importante (?), attention), dans le meme dossier que le fichier .ino du transeiver.

je compile et a nouveau une erreur, malgré le fait que j'ai mis dans le meme dossier, il ne le trouve pas.
en cherchant la doc, j'ai compris que la syntaxe quand c'est un fichier n'est pas de le mettre entre < > mais " ".
je corrige donc en

Code : Tout sélectionner

#include "SerialTerminal.hpp"
tout en étant très surpris de devoir faire ce genre de correction sans que personne nule part en ai parlé ?

attention aussi quand vous allez creer votre fichier .hpp au format d'encodage du texte, vous pourriez avoir plein de petite erreur.
le mieux, pour ne pas se tromper, est d'ouvrir un nouvel onglet propre dans l'IDE, d'y copier / coller le texte directement, puis de sauvegarder depuis l'IDE.

cette fois ci, apres un CTRL+U, ca compile entièrement, ça passe.

reste à tester :
Ouvrir le moniteur série et régler la vitesse sur 57600.
Dans le moniteur série, taper la commande suivante : ERS 3 30
La chaudière doit démarrer et réguler la température de l'eau à 30 degrés
cette fois ci, c'est bien 57600 puisque c'est ainsi que c'est configuré sur le transeiver, contrairement à la version modifié de recepteur plus haut.

j'ai bien fait ce test, mais ...
.... je n'ai constaté AUCUN effet.

que faire ?

en outre, je me demande : comment la chaudiere se comporte en cas de reception d'ordre contradictoire entre le thermostat d'origine et le RFlink ? j'imagine qu'il faut retirer les piles du thermostat d'origine, tout simplement, non ?
d'ailleurs, sous question : n'y a t'il pas moyen de conserver en back le thermostat ?
j'imagine, pourquoi pas, creer un systeme avec un relais "normalement fermé" entre un set de pile et le thermostat. et raccorder ce relais a mon systeme domotique. il faut une COMMANDE pour le laisser ouvert (et donc le débrancher)
en cas de panne, le relais va fermer tout seul, du coup le thermostat sera a nouveau alimenté et s'activera.
par contre avec la prog d'origine, puisque je crois pas qu'il garde sa prog sans batterie. mais c'est toujours mieux que rien.
qu'en pensez vous ? quelqu'un a t'il deja fait ce genre de chose ?

il est fort dommage par contre de ne pas avoir de retour d'info de la chaudière, température, activation de la flamme, etc ... peut etre un jour prendrais je le temps de hacker la face avant de celle ci pour récupérer les états des lumières, voir commander les boutons, pour remonter les codes de panne ou autre.
je pourrais meme remplacer les deux petit robinet de remise en pression par des electrovanne pour commander un rechargement du circuit en automatique.
j'imagine qu'en utilisant de simple optocoupleur soudé en parrallèle des leds, et des relais pour les boutons / bouton poussoir, y'a moyen assez facilement de faire quelque chose.
ca sera un bon projet cet été, je pense :)
je partagerais ça ici, j'imagine que ca donnera des idées à des gens ...

a noter aussi que j'ai 3 capteurs de température (eau froide, eau chaude chauffage départ, eau chaude chauffage arrivé) et un compteur d'eau sur le circuit de chauffage ... autrement dit, de quoi faire un compteur thermique.
j'ai aussi 2 capteurs de pression sur l'arrivée d'eau générale, et sur le circuit de chauffage.

ca promet de petit montage sympa.
je suis par contre sur jeedom. désolé, je suis pas sur le bon fofo... mais le fait est que pour parler de cette bécane gaz, c'est, et de très loin, le meilleur topic possible. donc je pense que personne me le reprochera ^^

bravo en tout cas pour toute vos contribution passé. ca reste impressionnant.

merci d'avance a ceux qui pourront m'aider à comprendre ce qui continue de déconner avec le systeme actuel; je pense ne pas être très loin du résultat, mais bon ....
et j'espère que ma petite contribution / aide pourra servir aux prochains :)

Re: [Tuto] Régulation d'une chaudière Frisquet ECO radio System

Publié : 05 avr. 2022, 11:51
par christopheHD
insosama a écrit : 05 avr. 2022, 00:40 d'abord, le fichier =>
Dans ton fichier, tu as juste rajouté une ligne "Hello World" et tu as modifié la vitesse du port série, c'est donc normal qu'il faille renseigner 115200 au lieu de 57600.
insosama a écrit : 05 avr. 2022, 00:40 les broches 19,15,22 me laissent penser que ca été corrigé ?
Non, mais je viens de le faire grâce à la contribution de hakkanicko sur le Github. Je ne peux cependant pas tester car j'ai module plus ancien qui n'utilise pas ces PIN.
insosama a écrit : 05 avr. 2022, 00:40 tout en étant très surpris de devoir faire ce genre de correction sans que personne nule part en ai parlé ?
Bien vu, j'avais oublié ce point dans ma documentation, j'ai mis à jour le Wiki.
insosama a écrit : 05 avr. 2022, 00:40 j'ai bien fait ce test, mais ...
.... je n'ai constaté AUCUN effet.

que faire ?
Teste à nouveau avec la dernière version du fichier, comme indiqué précédemment j'ai apporté des changements grâce à une contribution de hakkanicko.
insosama a écrit : 05 avr. 2022, 00:40 comment la chaudiere se comporte en cas de reception d'ordre contradictoire entre le thermostat d'origine et le RFlink ? j'imagine qu'il faut retirer les piles du thermostat d'origine, tout simplement, non ?
d'ailleurs, sous question : n'y a t'il pas moyen de conserver en back le thermostat ?
La chaudière prendra toujours le dernier ordre reçu, il faut donc débrancher le thermostat d'origine lorsque l'on utilise cette solution.

Re: [Tuto] Régulation d'une chaudière Frisquet ECO radio System

Publié : 18 avr. 2022, 10:39
par benoit.divers.91
Salut,

J'ai un peu disparu des écrans radar pendant qqes temps, on a pas tjs le temps qu'on voudrait :?

J'ai bien réussi à piloter la chaudière avec le code suivant:

Code : Tout sélectionner

#include <SerialTerminal.hpp>

#define TRANSCEIVER_TX_PIN      14
#define TRANSCEIVER_MODE_PIN    15    // Aurel transceivers have a pin that let the hardware switch to RX and TX mode
#define TRANSCEIVER_ENABLE_PIN  22    // Aurel transceivers have a pin that must be set to HIGH to enable the transmitter

// DO NOT CHANGE THESE SETTINGS BELOW
#define TRANSCEIVER_TX HIGH
#define TRANSCEIVER_RX  LOW

// Variables
byte ERS_pin = TRANSCEIVER_TX_PIN;
int long_pulse = 825;
byte message[17] = {0x00, 0x00, 0x00, 0x7E, 0x6A, 0xF4, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x00, 0xFF, 0x80};
byte old_state, num_byte;
byte bitstuff = 0;
maschinendeck::SerialTerminal* term;

void writeBit(bool Bit) {
  old_state = !old_state;
  digitalWrite(ERS_pin, old_state);
  delayMicroseconds(long_pulse);

  if (Bit) {
    old_state = !old_state;
    digitalWrite(ERS_pin, old_state);
  }
  delayMicroseconds(long_pulse);
}

void conversion(byte input) {
  for (byte n = 0; n < 8; n++) { // boucle pour chaque bit
    writeBit(bitRead(input, n));
    if (num_byte >= 4 && num_byte <= 14) {
      if (bitRead(input, n) == 1)
        bitstuff++;  // incrémente le compteur bitstuffing
    }
    if (bitRead(input, n) == 0)
      bitstuff = 0;
    if (bitstuff >= 5) {
      writeBit(0);
      bitstuff = 0;
    }
  }
}

void commande(byte prechauffage, byte chauffage) {
  if ((chauffage <= 100) and ((prechauffage==0) or (prechauffage==3) or (prechauffage==4))) {
    for (byte x = 0; x < 3; x++) { // boucle de 3 messages
      old_state = 0;
      message[9] = x;  // numero message : 0 à 2
      if (x == 2) {
        message[10] = prechauffage;
      } else {
        message[10] = prechauffage + 0x80;
      }
      message[11] = chauffage;
      
      int checksum = 0;
      for (int i = 4; i <= 12; i++) {
        checksum -= message[i];
      }
      message[13] = highByte(checksum);
      message[14] = lowByte(checksum);

      Serial.println("Trame envoyée : ");
      for (byte i = 1; i <= 16; i++) {
        if (message[i] <= 0x0F)
          Serial.print("0");
        Serial.print(message[i], HEX);
      }
      Serial.println("");
      for (num_byte = 1; num_byte < 17; num_byte++) { // boucle de 16 bytes
        conversion(message[num_byte]);
      }
      digitalWrite(ERS_pin, LOW);
      delay(33);
    }
    digitalWrite(ERS_pin, LOW);
  } else {
    return;
  }
}

void ERS_command(String opts) {
  digitalWrite(LED_BUILTIN, HIGH);
  maschinendeck::Pair<String, String> operands = maschinendeck::SerialTerminal::ParseCommand(opts);
  int mode = operands.first().toInt();
  Serial.print("Mode : ");
  switch (mode) {
    case 0:
      Serial.println("Réduit");
      break;
    case 3:
      Serial.println("Confort");
      break;
    case 4:
      Serial.println("Hors gel");
      break;
    default:
      Serial.print("Inconnu (");
      Serial.print(mode);
      Serial.println(")");
  }
  
  Serial.print("Température d'eau ");
  Serial.print(operands.second());
  Serial.println(" degré(s)");
  
  commande(mode,operands.second().toInt());   // reduit 0, confort 3, hors gel 4, chauffage 0 à 100
  Serial.print("Commande envoyée");
  digitalWrite(LED_BUILTIN, LOW);
}

void setup() {
  // set the Aurel transceiver to RX mode
  pinMode(TRANSCEIVER_MODE_PIN, OUTPUT);
  digitalWrite(TRANSCEIVER_MODE_PIN, TRANSCEIVER_TX);

  // enable Aurel transmitter
  pinMode(TRANSCEIVER_ENABLE_PIN, OUTPUT);
  digitalWrite(TRANSCEIVER_ENABLE_PIN, HIGH);

  pinMode(TRANSCEIVER_TX_PIN, OUTPUT);
  digitalWrite(TRANSCEIVER_TX_PIN, LOW);

  pinMode (LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
 
  term = new maschinendeck::SerialTerminal(57600);
  term->add("ERS", &ERS_command, "ERS mode heat\nmode : 0=Reduit, 3=Confort, 4=Hors gel\nheat : Température de chauffage entre 0 et 100");
}

void loop() {
 term->loop();
}
Pas de difficultés majeures, une fois le pb de la configuration passé.

J'ai un peu laissé de côté le pilotage ensuite, et je suis passé dans l'interfaçage sous Domoticz.
J'ai donc un peu revu le script de décodage des trames pour que ça communique avec mon RPi:

Code : Tout sélectionner

#define TRANSCEIVER_RX_PIN      19    // Set the pin that receives data from your 433.42 Mhz Receiver
#define TRANSCEIVER_MODE_PIN    15    // Aurel transceivers have a pin that let the hardware switch to RX and TX mode
#define TRANSCEIVER_ENABLE_PIN  22    // Aurel transceivers have a pin that must be set to HIGH to enable the transmitter

// DO NOT CHANGE THESE SETTINGS BELOW
#define TRANSCEIVER_TX HIGH
#define TRANSCEIVER_RX  LOW

#define SERIAL_MONITOR  0x01
#define RASPBERRY_PI    0x10  
#define INTERFACE_MODE  RASPBERRY_PI

volatile long duration = 0;
volatile long prev_time = 0;
volatile boolean data_dispo = false;
byte input = TRANSCEIVER_RX_PIN;
String trame[3];
byte message = 0;
byte start = true;
byte intro = 0;
String prefixe = "1100";
 
void setup() {
  Serial.begin(115200);
  // set the Aurel transceiver to RX mode
  pinMode(TRANSCEIVER_MODE_PIN, OUTPUT);
  digitalWrite(TRANSCEIVER_MODE_PIN, TRANSCEIVER_RX);

  // enable Aurel transmitter
  pinMode(TRANSCEIVER_ENABLE_PIN, OUTPUT);
  digitalWrite(TRANSCEIVER_ENABLE_PIN, HIGH);

  delay(500);

  // assign an interrupt on pin x on state change
  pinMode(TRANSCEIVER_RX_PIN, INPUT);
  attachInterrupt(digitalPinToInterrupt(input), declenche, CHANGE);
  
  pinMode (LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
}
 
void loop() {
  if (data_dispo == true) {
    int bit_state = digitalRead(input);
    if ((duration > 700) && (duration < 950)) { // pulse off court
      trame[message] = trame[message] + !bit_state;
    } else if ((duration > 1400) && (duration < 1950)) { // pulse off long
      // verifie qu'on commence avec un pulse long à 1
      if ((start == true) && (!bit_state == HIGH)) {
        trame[message] = trame[message] + !bit_state + !bit_state;
        start = false;
      } else if (start == false) {
        trame[message] = trame[message] + !bit_state + !bit_state;
      }
    } else {
      start = true; // debut d'une nouvelle trame
      if (trame[message].length() > 200) {
        message++;
        if (message > 2) {
          for (message = 0; message < 3; message++) {
            for (int x = 0; x <= 50; x=x+4) {
              if (trame[message].substring(x,x+4).compareTo(prefixe) == 0) {
                intro++;
              } else {
                break;
              }
            }
            if (intro > 6 ) {
              digitalWrite(LED_BUILTIN, HIGH);
              // décodage des bits de la trame: 00=0, 11=0, 10=1, 01=1
              String sortie = "";
              for (int x = (intro*4); x <= trame[message].length(); x=x+2) {
                if ((trame[message].substring(x,x+2) == "00") or (trame[message].substring(x,x+2) == "11")) {
                  sortie = sortie + "0";
                } else {
                  sortie = sortie + "1";
                }
              }
              String sortie_without_bitstuff = remove_bitstuff(sortie);
              sortie = sortie_without_bitstuff;
              String sortie_hex = convert_binary_string_to_hex_string(sortie);
#if INTERFACE_MODE == SERIAL_MONITOR
              Serial.print("Trame reçue :");
              Serial.println(sortie_hex);
#endif
              // repartition en bytes
              byte id1 = convert(sortie.substring(0,8)); // byte 3
              byte id2 = convert(sortie.substring(8,16)); // byte 4
              byte id3 = convert(sortie.substring(16,24)); // byte 5
              byte num = convert(sortie.substring(48,56)); // byte 9 (repeat)
              byte prechauff = convert(sortie.substring(56,64)); // byte 10 (pre-heated) 0=Reduit, 3=Confort, 4=Hors gel
              byte chauffage = convert(sortie.substring(64,72)); // Heating
              byte battery = convert(sortie.substring(72,80)); // Battery
#if INTERFACE_MODE == SERIAL_MONITOR
              Serial.print("Message #");
              Serial.println(num);
              Serial.print("ID: ");
              Serial.print(id1, HEX);
              Serial.print("-");
              Serial.print(id2, HEX);
              Serial.print("-");
              Serial.println(id3, HEX);
              Serial.print("Mode : ");
              prechauff &= 0x0F;
              switch (prechauff) {
                case 0:
                  Serial.println("Réduit");
                  break;
                case 3:
                  Serial.println("Confort");
                  break;
                case 4:
                  Serial.println("Hors gel");
                  break;
                default:
                  Serial.print("Inconnu (");
                  Serial.print(prechauff);
                  Serial.println(")");
              } 
              Serial.print("Température eau : ");
              Serial.println(chauffage);
              Serial.print("Batterie : ");
              if (battery > 0)
                Serial.println("LOW");
              else
                Serial.println("OK");
              if (num > 1)
                Serial.println("##########");
              else
                Serial.println("----------");
#elif INTERFACE_MODE == RASPBERRY_PI
              // {ID;MODE;TEMP;BATT}
              String msgSend = "";
              msgSend = String(msgSend + id1 + "-" + id2 + "-" + id3);

              prechauff &= 0x0F;
              msgSend = String(msgSend + ";" + prechauff);

              msgSend = String(msgSend + ";" + chauffage);

              msgSend = String(msgSend + ";");
              if (battery > 0)
                msgSend = String(msgSend + "0");
              else
                msgSend = String(msgSend + "1");

              Serial.println(msgSend);              
#else
    #error Wrong Serial Interface Configuration
#endif
              intro = 0;
              digitalWrite(LED_BUILTIN, LOW);
            }
          }  
          trame[0] = "";
          trame[1] = "";
          trame[2] = "";
          message = 0;
        }
      } else {
        // Re-initialise la trame s'il n'y avait pas de données juste avant      
        if ((message == 0) || (trame[message-1].length() < 200)) { 
          trame[0] = "";
          trame[1] = "";
          trame[2] = "";
          message = 0;
        }
      }
    }
    data_dispo = false;
  }
}

void declenche() {
  duration = micros()-prev_time;
  prev_time = micros();
  data_dispo = true;
}

byte convert(String entree) {
  byte result = 0;
  for (int f = 0; f <= 7 ; f++) {
    if (entree.substring(f,f+1) == "1") bitSet(result, f);
  }
return result;
}

String convert_binary_string_to_hex_string(String data) {
  String sortie = "";
  for (int x = 0; x < (data.length()/8);x++) {
    byte hex = 0;
    for (int f = 0; f <= 7 ; f++) {
      if (data.substring((x*8)+f,(x*8)+f+1) == "1")
        bitSet(hex, f);
    }
    if (hex <= 0x0F)
      sortie += "0";
    sortie += String(hex, HEX);
  }
  sortie.toUpperCase();
  return sortie;
}

String remove_bitstuff(String data) {
  // The protocol uses bit-stuffing => remove 0 bit after five consecutive 1 bits
  // Also, each byte is represented with least significant bit first -> swap them!
  String sortie = "";
  int ones = 0;
  for (uint16_t k = 0; k < data.length(); k++) {
    if (data[k] == '1') {
      sortie += "1";
      ones++;
    } else {
      if (ones != 5) // Ignore a 0 bit after five consecutive 1 bits:
        sortie += "0";
      ones = 0;
    }
  }
  return sortie;
}
Et côté RPi, j'ai choisi de mettre à jour régulièrement Domoticz via les API JSON dans un script Python:

Code : Tout sélectionner

#!/usr/bin/python

import serial
import requests
import time
import json

DomoticzIP   = '' #moi j'utilise l'ip locale
DomoticzPort = '' #ton port

# Frisquet - Commande    idx:119   
# Frisquet - Mode        idx:120   {0:Hors-Gel(4) ; 10:Reduit(0) ; 20:Confort(3)}
# Frisquet - Batterie    idx:121   {0:OK(0) ; 10:LOW(1)}
FrisquetID   = '' #ton ID Frisquet au format XXX-XXX-XXX
FrisquetMode = {'0':'10','3':'20','4':'0'}
FrisquetBatt = {True:'0',False:'10'}
mode = ''
batt = ''
temp = ''

VERBOSE = False
def Debug(str):
    if VERBOSE:
        print(str)

if __name__ == '__main__':
    ser = serial.Serial('/dev/ttyACM0',115200)
    ser.flush()
    
    msgValid = False
    urlBase = 'http://' + DomoticzIP + ':' + DomoticzPort + '/json.htm?type=command&param={param}&idx={idx}&{msg}'
    
    Debug("Verbose mode: ON")
    url = 'http://' + DomoticzIP + ':' + DomoticzPort + '/json.htm?type=command&param=addlogmessage&message=FRISQUET:%20Monitoring ON'
    response = requests.get(url)

    while True:
        if msgValid:
            Debug("Valid message received")
            delayTime = 1
            # TEMP: /json.htm?type=command&param=udevice&idx=IDX&nvalue=0&svalue=PERCENTAGE
            # Frisquet - Commande    idx:119   
            urlEnd = 'nvalue=0&svalue=' + temp
            url = urlBase.format(param='udevice', idx='119', msg=urlEnd)
            response = requests.get(url)
            time.sleep(delayTime)
            if(response.ok):
                Debug("TEMP: Positive URL response")
                result = json.loads(response.content)
                Debug(str(result))
            else:
                Debug("TEMP: Negative URL response")
            
            # SWITCH: /json.htm?type=command&param=switchlight&idx=IDX&switchcmd=Set%20Level&level=LEVEL
            # Frisquet - Mode        idx:120   {0:Hors-Gel ; 10:Reduit ; 20:Confort}
            urlEnd = 'switchcmd=Set%20Level&level=' + mode
            url = urlBase.format(param='switchlight', idx='120', msg=urlEnd)
            response = requests.get(url)
            time.sleep(delayTime)
            if(response.ok):
                Debug("MODE: Positive URL response")
                result = json.loads(response.content)
                Debug(str(result))
            else:
                Debug("MODE: Negative URL response")            
            
            # Frisquet - Batterie    idx:121   {0:OK ; 10:LOW}
            urlEnd = 'switchcmd=Set%20Level&level=' + batt
            url = urlBase.format(param='switchlight', idx='121', msg=urlEnd)
            response = requests.get(url)
            time.sleep(delayTime)
            if(response.ok):
                Debug("BATT: Positive URL response")
                result = json.loads(response.content)
                Debug(str(result))
            else:
                Debug("BATT: Negative URL response")            

            Debug('')
            msgValid = False
                    
        if ser.in_waiting > 0:
        # ID;MODE;TEMP;BATT
            line = ser.readline().decode('utf-8').rstrip()
            # line = line.encode('ascii')
            line = line.split(';')
            Debug('Frame received')
            Debug(str(line))
            
            if line[0] == FrisquetID:
                Debug('ID in frame is correct')
                msgValid = True
                if line[1] in ['0','3','4']:
                    Debug('Mode in frame is known')
                    mode = FrisquetMode[line[1]]
                    temp = line[2]
                    batt = FrisquetBatt[line[3]>0]
                else:
                    Debug('Mode in frame is unknown')
                    msgValid = False
            Debug('')
        else:
            Debug('Nothing received standby')
            time.sleep(5)

        # if(response.ok):
        #     result = json.loads(response.content)
Il manque des paramètres pour les devices Domoticz que vous utiliserez, j'ai codé les miens en dur (idx:119/120/121).
Pareil pour l'IP et le PORT, de mon côté j'utilise 127.0.0.1, vu que le PI s'appelle lui même ...


A ce stade, je mets des sous de côté pour basculer mes têtes de chauffage en ZigBee.
J'en ai qu'une pour le moment (pour tester), ça coûte une c... / la peau des cacahuètes.
Mon idée étant de faire une synthèse du besoin en chauffage des différentes pièces et d'envoyer ensuite une demande de chauffage à la chaudière.
Il me faudra alors adapter le script de l'Arduino pour basculer entre Rx et Tx sur demande du RPi.

Bon, pas forcément super clair tout ça, je voulais repartager avec vous rapidement.

Bon courage !

Re: [Tuto] Régulation d'une chaudière Frisquet ECO radio System

Publié : 08 mai 2022, 23:38
par ParkerLewis
Salut @benoit.divers.91,

Merci beaucoup pour ton retour ! J'avais moi aussi mis le sujet de côté depuis un bon mois, ravi de revenir et de voir ta contribution.

Je vais essayer de tester ces jours-ci. Y a des choses qui m'éotnnent à la lecture : la syntaxe de la première ligne, si comme évoqué plus haut c'est pas la bonne ; et je comprends pas pourquoi ce serait encore le pin 14 en transmission, en lisant la doc de l'Aurel j'avais cru comprendre que ça devrait être le 19...

Mais bon à la rigueur peu importe. Si ça marche chez toi c'est que ça doit être bon... Je teste ces jours-ci et ferai un retour

Merci encore en tout cas