Volets somfy - telecommande rts

Bonsoir dfgh,

Je vous livre quelques infos sur la trame gérée par la télécommande émulée sur la pro mini.

Je comprends qu'elle présente les caractéristiques suivantes :

  • elle est stockée dans l'eeprom de l'arduino ;
  • elle est constituée de 56 bits donc 7 octets :
  • le premier octet c'est la clé random pour le cryptage (peut-être un code manchester) ;
  • les 4 premiers bits du deuxième octet contiennent la commande (UP-DOWN-STOP) ;
  • les 4 derniers bits du deuxième octet , je ne sais pas (etimou appelle ça le checksum);
  • le troisième et le quatrième octet contiennent le rolling code ;
  • le 5ème, le sixième et le septième octet contiennent la fameuse adresse qui permet d'émuler une télécommande sur la pro mini...

Cette trame est gérée dans la librairie d'etimou ici :

void SomfyRTS::buildFrameSomfy() {
  uint16_t Code;
  EEPROM.get(_EEPROM_address + 2 * _virtualRemoteNumber, Code);
  frame[0] = 0xA7; // Encryption key. Doesn't matter much
  frame[1] = _actionCommand << 4;  // Which button did  you press? The 4 LSB will be the checksum
  frame[2] = Code >> 8;    // Rolling code (big endian)
  frame[3] = Code;         // Rolling code
  frame[4] = _RTS_address + _virtualRemoteNumber >> 16; // Remote address
  frame[5] = _RTS_address + _virtualRemoteNumber >>  8; // Remote address
  frame[6] = _RTS_address + _virtualRemoteNumber;     // Remote address

  //Serial.print("Frame         : ");
  for (byte i = 0; i < 7; i++) {
    if (frame[i] >> 4 == 0) { //  Displays leading zero in case the most significant
      //Serial.print("0");     // nibble is a 0.
    }
    //Serial.print(frame[i],HEX); Serial.print(" ");
  }

  // Checksum calculation: a XOR of all the nibbles
  byte checksum = 0;
  for (byte i = 0; i < 7; i++) {
    checksum = checksum ^ frame[i] ^ (frame[i] >> 4);
  }
  checksum &= 0b1111; // We keep the last 4 bits only


  //Checksum integration
  frame[1] |= checksum; //  If a XOR of all the nibbles is equal to 0, the blinds will
  // consider the checksum ok.

  //Serial.println(""); Serial.print("With checksum : ");
  for (byte i = 0; i < 7; i++) {
    if (frame[i] >> 4 == 0) {
      //Serial.print("0");
    }
    //Serial.print(frame[i],HEX); Serial.print(" ");
  }


  // Obfuscation: a XOR of all the bytes
  for (byte i = 1; i < 7; i++) {
    frame[i] ^= frame[i - 1];
  }

  //Serial.println(""); Serial.print("Obfuscated    : ");
  for (byte i = 0; i < 7; i++) {
    if (frame[i] >> 4 == 0) {
      //Serial.print("0");
    }
    //Serial.print(frame[i],HEX); Serial.print(" ");
  }
  //Serial.println("");
  //Serial.print("Rolling Code  : "); Serial.println(code);
  EEPROM.put(_EEPROM_address + 2 * _virtualRemoteNumber, ++Code); //  We store the value of the rolling code in the
  // EEPROM. It should take up to 2 adresses but the
  // Arduino function takes care of it.
  #ifdef ESP8266
  EEPROM.commit();
  #endif
}

On voit bien dans ce bout de code les détails de cette trame :

EEPROM.get(_EEPROM_address + 2 * _virtualRemoteNumber, Code);
  frame[0] = 0xA7; // Encryption key. Doesn't matter much
  frame[1] = _actionCommand << 4;  // Which button did  you press? The 4 LSB will be the checksum
  frame[2] = Code >> 8;    // Rolling code (big endian)
  frame[3] = Code;         // Rolling code
  frame[4] = _RTS_address + _virtualRemoteNumber >> 16; // Remote address
  frame[5] = _RTS_address + _virtualRemoteNumber >>  8; // Remote address
  frame[6] = _RTS_address + _virtualRemoteNumber;     // Remote address

Un tableau frame à 7 éléments gère donc ces 7 octets soit 56 bits.
J'ai également cru comprendre que la transmission de la trame complète selon le protocole RTS est de l’ordre de 140 ms, en incluant la synchronisation hardware, la synchronisation software.

Bonne soirée.
PS : c'est mon analyse, elle est peut-être erronée...