pimatic / pimatic

A home automation server and framework for the raspberry pi running on node.js
http://pimatic.org
GNU General Public License v2.0
598 stars 145 forks source link

Support for Silvercrest/rolling code switches #386

Closed keematic closed 9 years ago

keematic commented 9 years ago

First of all, thanks for developing pimatic.

I'm busy running the pimatic installation, finally got it working (with an Arduino Uno being recognized as ttyACM0 instead of ttyUSB0).

I have two sets of switches, Eurodomest and Silvercrest. I sniffed both transmitters with some Arduino code and got a hold of the binary codes. The Eurodomest is recognized as switch5 in pimatic-homeduino, as it should. The Silvercrest however was found to have a rolling set of 4 codes for each button with the piece of Arduino code mentioned before. Unfortunately the protocol was not recognized in homeduino.

The weird thing is the binary button-code received by pimatic is not rolling between 4 different ones, but only one code which end in '23'.

If there's a possibility to somehow support rolling codes, it'd be great (increased security for 'sensitive' devices)! I can post the binary codes for all buttons if needed.

Cheers

Icesory commented 9 years ago

Show some debug data. Then we can take a look on it.

keematic commented 9 years ago

These are the binary codes (through the Arduino code, not pimatic) for the ON-buttons. Codes are rolled in this order.

A on 011111110000111001011100 011101101101100010101100 011111011110001001101100 011110011010111100011100

B on 011111100100010000110101 011100001000110111110101 011111000110101111100101 011101000010000100000101

C on 011100010001011100101110 011101110011101010001110 011110001011100110111110 011110101001110001111110

D on 011100100111010101000111 011110111111011011000111 011100111100000010010111 011101010101001111010111

ALL on 011100010001011100100010 011110101001110001110010 011110001011100110110010 011101110011101010000010

I have the codes in Excel. Found a few patterns in them

Icesory commented 9 years ago

I cant see a system in the whole message. But it is easy possible to hardcode alle messages in lists. In the FHEM Forum exist a huge thread about this but without a result.

can you post all off comands too? Than i would try to make a "list" protocol. and i need min one raw code message.

Is it right, the system contains of maximum 4 different units?

keematic commented 9 years ago

Thanks for helping. Yes, 4 different units/groups, but all switches can respond to one button/group (assigning them to A for example). In addition, a switch can respond to multiple transmitters (6 max, which is kind of cool if you lose a remote control ;) ).

Here are the binary OFF codes: A off 011110001011100110111100 011110101001110001111100 011100010001011100101100 011101110011101010001100

B off 011100111100000010010101 011101010101001111010101 011100100111010101000101 011110111111011011000101

C off 011110011010111100011110 011111110000111001011110 011101101101100010101110 011111011110001001101110

D off 011100001000110111110111 011111000110101111100111 011101000010000100000111 011111100100010000110111

ALL off 011110011010111100010010 011111011110001001100010 011101101101100010100010 011111110000111001010010

Important thing to note is that just sending either of these four binary codes to the switches does not work. So it is protected to 'relay attacks'. I tried to just re-send all four ON codes of switch A, but that is not working. I suppose there is some timing or order algorithm that 'protects' the signal from being intercepted and re-send. The four rolling codes only occur in the above order if you continuously press the same button. If for example you press A on, ALL off and then A on, the last binary intercepted will not be the second code of A.

Icesory commented 9 years ago

Have you tried to send one code 4-6 times in a row? In this thread it is possible to control the units with one code. http://forum.fhem.de/index.php?topic=27944.0

keematic commented 9 years ago

Yes, I tried to send all codes multiple times. No success. Maybe there's is some difference in the pulse length? The pulse length reported by Arduino is 102microsec, which is a bit short. I think there's some changing variation in the length, so the switch doesn't pick up the right code.

keematic commented 9 years ago

Update: I got a working example! Adapted and simplified from Poopi (http://forum.arduino.cc/index.php?topic=202556.0). I removed some code and adapted it to my own code, though only for A in my case. I'll have to add the other codes later. It seems the timings are a bit more difficult and needs syncing to be able to receive. Is there any chance this is implementable in pimatic?


/*
SilverCrest 91210 RCS AAA3680 - A IP20
Below code will transmit on and off signals to SilverCrest 91210 Remote Electrical Sockets

Based on code from http://forum.arduino.cc/index.php?topic=202556.msg1492685#msg1492685
Modifed by Poopi, Tested on Teensy 2.0++
Modified/simplified by keematic on 19 Nov 2014

Sequence had two distinct sub sequences - 
1. 4x with short sync and short '1's 
2. 4x with long sync and longer '1's

Codes were cycled - 4 different codes per each plug but you can choose any of these codes - I used all to mimic original RCU
Seems that 4 last bits are a PLUG identifier and first 4 bits are a remote identifier

Remaining 16 bits seems to be common for all plugs ( Plug C have reverted On/Off sequences sic! )
All codes captured from original RCU usin logic analyzer

Pin 10 - transmit
Pin 5V - VCC of the transmitter
Pin Ground - Ground of the transmitter

LED on pin 6 flashes while sending signal
*/

#define DEBUG

#define RF_DATA_PIN    10 //Digital pin 10
#define BLINK_LED_PIN  13 //Digital LED pin 13

#define MAX_CODE_CYCLES 4

#define SHORT_DELAY       380
#define NORMAL_DELAY      500
#define SIGNAL_DELAY     1500

#define SYNC_DELAY       2650
#define EXTRASHORT_DELAY 3000
#define EXTRA_DELAY     10000

enum {
  PLUG_A = 0,
  PLUG_B,
  PLUG_C,
  PLUG_D,
  PLUG_MASTER,
  PLUG_LAST
};

unsigned long signals[PLUG_LAST][2][MAX_CODE_CYCLES] = {
  { /*A*/
    {0b011111110000111001011100, 0b011101101101100010101100, 0b011111011110001001101100, 0b011110011010111100011100}, 
    {0b011110001011100110111100, 0b011110101001110001111100, 0b011100010001011100101100, 0b011101110011101010001100}
  },  

/* !!! insert other codes (ON/OFF) for B, C, D and Master !!!! */

};

boolean       onOff;
unsigned char plug;
unsigned char swap;

void setup() {                
  pinMode(BLINK_LED_PIN, OUTPUT);
  pinMode(RF_DATA_PIN, OUTPUT);
  pinMode(13, OUTPUT);
  Serial.begin(9600);
  Serial.println("Ready");
  onOff = 1;
  swap  = 0;
  plug  = PLUG_A;
}

void loop() {  
    digitalWrite(BLINK_LED_PIN,HIGH);
    ActivatePlug(plug,onOff);
    digitalWrite(BLINK_LED_PIN,LOW);

    onOff = !onOff;
    delay(500);  
}

void sendSync(){
  digitalWrite(RF_DATA_PIN, HIGH);
  delayMicroseconds(SHORT_DELAY);
  digitalWrite(RF_DATA_PIN, LOW);
  delayMicroseconds(SYNC_DELAY - SHORT_DELAY);  
}

void sendValue(boolean value, unsigned int base_delay){
  unsigned long d = value? SIGNAL_DELAY - base_delay : base_delay;
  digitalWrite(RF_DATA_PIN, HIGH);
  delayMicroseconds(d);
  digitalWrite(RF_DATA_PIN, LOW);
  delayMicroseconds(SIGNAL_DELAY - d);
}

void longSync(){
  digitalWrite(RF_DATA_PIN, HIGH);
  delayMicroseconds(EXTRASHORT_DELAY);
  digitalWrite(RF_DATA_PIN, LOW);
  delayMicroseconds(EXTRA_DELAY - EXTRASHORT_DELAY);  
}

void ActivatePlug(unsigned char PlugNo, boolean On) {
    digitalWrite(RF_DATA_PIN,LOW);
    delayMicroseconds(1000);

    unsigned long signal = signals[PlugNo][On][swap];

    swap++;
    swap%=MAX_CODE_CYCLES;

 #ifdef DEBUG
    Serial.print("PLUG_");
    Serial.print(plug == PLUG_MASTER?'M':(char)('A'+plug));
    Serial.write (" Code: ");
    Serial.print(swap);
    Serial.print(" ");
    Serial.println(onOff?"On":"Off");
    Serial.println(signal, BIN);
 #endif

    for (unsigned char i=0; i<4; i++) { // repeat 1st signal sequence 4 times
      sendSync();
      for (unsigned char k=0; k<24; k++) { //as 24 long and short signals, this loop sends each one and if it is long, it takes it away from total delay so that there is a short between it and the next signal and viceversa
        sendValue(bitRead(signal, 23-k),SHORT_DELAY);
      }    
    }
    for (unsigned char i=0; i<4; i++) { // repeat 2nd signal sequence 4 times with NORMAL DELAY
      longSync();  
      for (unsigned char k=0; k<24; k++) {
        sendValue(bitRead(signal, 23-k),NORMAL_DELAY);
      }
    }  
}
Icesory commented 9 years ago

Ok. The algorithm which encode the compressed timings are different to the Homeduino algorithm. Can you pls use the RFControl library to pickup the raw and compressed timings. https://github.com/Icesory/RFControl First capture one package with the raw example. And then all other with the compressed example. We can only work with this outputs at the moment.

keematic commented 9 years ago

Alright, a couple of raw pickups of button A-On:

456 1084 960 576 960 576 956 580 444 1092 956 584 952 580 444 1096 
952 576 960 572 452 1088 960 576 960 572 452 1084 452 1088 448 1092 
952 588 440 1096 948 584 440 1092 956 576 960 580 448 1084 452 1092 
2996 7260 

452 1092 956 572 960 576 960 576 960 572 452 1088 448 1084 964 572 
964 568 456 1088 960 572 452 1084 960 576 960 572 964 576 956 576 
452 1084 452 1088 448 1084 960 572 968 572 960 572 456 1080 452 1092 
3000 7252 

448 1088 960 576 956 584 952 580 952 588 948 584 952 584 952 580 
444 1092 444 1092 448 1088 448 1084 960 580 956 576 960 576 448 1092 
444 1096 952 580 444 1092 952 584 952 584 952 580 444 1092 444 1096 
2996 7264 

436 1092 956 572 964 576 956 580 448 1084 960 576 960 576 448 1092 
956 580 956 580 444 1096 948 580 956 580 444 1092 448 1088 448 1088 
956 576 452 1084 960 576 448 1092 956 584 948 588 440 1092 444 1096 
2992 7256 

448 1092 956 576 956 580 956 576 960 576 960 584 440 1088 956 580 
956 580 956 580 956 580 444 1092 444 1092 444 1092 952 580 448 1088 
448 1092 956 580 952 576 452 1092 956 576 956 580 444 1096 440 1100 
2992 7252 

Compressed readings (all four codes) of all buttons:

A-ON:
b: 517 1018 2980 7252 0 0 0 0 
t: 01101010011010011010011010010101100110011010010123

b: 524 1010 2996 7256 0 0 0 0 
t: 01101010101001101010100101011001011010011010010123

b: 523 1011 2996 7256 0 0 0 0 
t: 01101010100101101001100110101010010101101010010123

b: 523 1012 2988 7252 0 0 0 0 
t: 01101010101010100101010110101001011001101010010123

A-OFF:
b: 507 1027 2996 7260 0 0 0 0 
t: 01101010010101100101011001101010010110011010010123

b: 517 1017 2992 7252 0 0 0 0 
t: 01101010011010100101101010011001100101011010010123

b: 524 1011 2988 7256 0 0 0 0 
t: 01101010100101011001101010010110100110101010010123

b: 523 1011 2988 7256 0 0 0 0 
t: 01101010100110011001011010100101011010101010010123

B-ON:
b: 530 1004 2984 7256 0 0 0 0 
t: 01101010101001010110100110011010101010010110011023

b: 491 1044 3000 7248 0 0 0 0 
t: 01101010011001010101100101010110010101010110011023

b: 512 1022 2996 7256 0 0 0 0 
t: 01101010101010010110010101100101010110100110011023

b: 517 1017 2984 7256 0 0 0 0 
t: 01101010010101011001010110100110101010100110011023

B-OFF:
b: 508 1027 2992 7248 0 0 0 0 
t: 01101010010110101010010101010101100101100110011023

b: 523 1011 2996 7252 0 0 0 0 
t: 01101010011001100110011001011010101001100110011023

b: 512 1022 2996 7256 0 0 0 0 
t: 01101010010110010110101001100110011001010110011023

b: 536 999 2984 7256 0 0 0 0 
t: 01101010100110101010101001101001101001010110011023

C-ON:
b: 523 1011 2988 7248 0 0 0 0 
t: 01101010011010100101101010011001100101011010100123

b: 528 1006 2988 7252 0 0 0 0 
t: 01101010100101011001101010010110100110101010100123

b: 530 1005 2996 7260 0 0 0 0 
t: 01101010100110011001011010100101011010101010100123

b: 512 1023 2996 7256 0 0 0 0 
t: 01101010010101100101011001101010010110011010100123

C-OFF:
b: 529 1006 2988 7252 0 0 0 0 
t: 01101010100101101001100110101010010101101010100123

b: 529 1005 2996 7252 0 0 0 0 
t: 01101010101010100101010110101001011001101010100123

b: 524 1011 2988 7252 0 0 0 0 
t: 01101010011010011010011010010101100110011010100123

b: 528 1006 2992 7252 0 0 0 0 
t: 01101010101001101010100101011001011010011010100123

D-ON:
b: 527 1009 3004 7248 0 0 0 0 
t: 01101010011001100110011001011010101001100110101023

b: 518 1018 3008 7244 0 0 0 0 
t: 01101010010110010110101001100110011001010110101023

b: 538 998 3008 7244 0 0 0 0 
t: 01101010100110101010101001101001101001010110101023

b: 512 1024 3012 7244 0 0 0 0 
t: 01101010010110101010010101010101100101100110101023

D-OFF:
b: 522 1012 2996 7244 0 0 0 0 
t: 01101010010101011001010110100110101010100110101023

b: 533 1001 2996 7252 0 0 0 0 
t: 01101010101001010110100110011010101010010110101023

b: 496 1038 3000 7248 0 0 0 0 
t: 01101010011001010101100101010110010101010110101023

b: 519 1016 2996 7248 0 0 0 0 
t: 01101010101010010110010101100101010110100110101023

ALL-ON:
b: 517 1018 3000 7248 0 0 0 0 
t: 01101010100101011001101010010110100110100101100123

b: 511 1024 3000 7244 0 0 0 0 
t: 01101010011010100101101010011001100101010101100123

b: 502 1033 3000 7244 0 0 0 0 
t: 01101010010101100101011001101010010110010101100123

b: 517 1017 3000 7244 0 0 0 0 
t: 01101010100110011001011010100101011010100101100123

ALL-OFF:
b: 516 1018 3000 7252 0 0 0 0 
t: 01101010101010100101010110101001011001100101100123

b: 517 1017 2996 7252 0 0 0 0 
t: 01101010100101101001100110101010010101100101100123

b: 518 1017 2996 7248 0 0 0 0 
t: 01101010101001101010100101011001011010010101100123

b: 512 1022 3000 7248 0 0 0 0 
t: 01101010011010011010011010010101100110010101100123

Thank you very much for helping out :)

keematic commented 9 years ago

Any luck on working out a solution? :)

Icesory commented 9 years ago

I am not able to decrypt the rolling system at the moment. We can make a protocol which only work for you. Problem is we can't add this to the repositories.

Icesory commented 9 years ago

Are you able to replace the files by your self?

https://github.com/Icesory/rfcontroljs/commit/dfbc280a5480f7704f522627fb0b56005b4c81d5

Icesory commented 9 years ago

Can you post a picture from the microcontroller on the remote? I would try to contact the producer for more information

keematic commented 9 years ago

I assume you made a custom switch (8) to let me control my own receiver? That is great! Though I'm not sure how to replace them by the default pimatic files. Care to help?

These are the pictures of the remote:

The microcontroller has 's007v0.1' as markup and has 14 pins. Quick google search doesn't state any producer.

Icesory commented 9 years ago

Wait pls with your update. We have now two options to make this protocol useable at the moment. First We create the protocol like the one i have done. But every user must change the values in the protocol for his own remote system. And after every update all files are reset.

Second I build a protocol prototype, which emit the received data to the homeduino device. The user must configure the binary code in the config like this:

    {
      "id": "Switch",
      "name": "RollingSchalter",
      "class": "HomeduinoRFSwitch",
      "protocols": [
        {
          "name": "switch8",
          "codeOn": ["1010001001....", "10111000110...", "etc."],
          "codeOff": ["0101000110....", "01010100010...", "etc."]
        }
      ]
    },

For this we need a little change in the Homeduino plugin.

@sweetpi what`s your opinion for this?

sweetpi commented 9 years ago

@Icesory I like the second solution. sending should be possible without changes, but receiving would need changes in pimatic-homeduino. If you like you can make a proposal.

Icesory commented 9 years ago

Ok i make this. But i think the protocol should not call "switch8". It is not a complete protocol implementation. I would call it "rollingCode". If the rolling code is open we should change this to an switch protocol.

Icesory commented 9 years ago

I have implemented the rollingCode protocol. To use this you must configure your device like this in your config

    {
      "id": "licht1",
      "name": "Licht1",
      "class": "HomeduinoRFSwitch",
      "protocols": [
        {
          "name": "rolling1",
          "options": {
            "codeOn": [
              "011111110000111001011100",
              "011101101101100010101100",
              "011111011110001001101100",
              "011110011010111100011100"
              ],
            "codeOff": [
              "011110001011100110111100",
              "011110101001110001111100",
              "011100010001011100101100",
              "011101110011101010001100"
              ]
          }
        }
      ]
    },

It is necessary to define min one value for codeOn AND codeOff else you can get an undefined exception.

To test this you must download it from my Git repository (homeduino and rfcontroljs) or you wait until @sweetpi add it to the official version.

Icesory commented 9 years ago

Save some Links for this topic. http://forum.pilight.org/Thread-Lidl-radio-outlets?page=2 http://forum.fhem.de/index.php?topic=27944.0 http://www.mikrocontroller.net/topic/305478

This software supports the RC-3600. These use the same protocol http://www.steckerchecker.de/kompatible-geraete/brennenstuhl/ http://www.l3x.de/connair/

keematic commented 9 years ago

Nice! Thank you very much. My German is a bit rusty, so I'll have to refresh it ;)

I hope some working implementation will be integrated into pimatic soon (I'm scared to crash my installation by using anything else besides the update function).

Oitzu commented 9 years ago

Tested the rollingcode protocol, works as expected.

fhempy commented 8 years ago

I managed to descramble the part which identifies the unit and ON/OFF state. Unfortunately I'm still stuck with the payload part. You can find more information here: https://forum.pilight.org/Thread-QUIGG-GT9000-Globaltronics-ALDI?pid=16489#pid16489

Just want to mention that here as well to get some more people on the topic. Maybe somebody has an idea on how to decode the payload.

Icesory commented 8 years ago

@dominikkarall I have looked into your stuff at pilight. But your payload isnt clear for me

ON2 3544    3749    603
OFF1    5171    4506    6521
OFF2    8645    9470    9098
OFF2    16102   15699   15345
OFF1    17963   18657   20271
ON1 23169   21772   20578
ON1 26036   27211   26606
ON2 30893   30322   31925
ON1 35679   33343   36502
OFF2    37641   39191   37288
ON1 43372   41912   42205
OFF2    45818   48084   48432
ON2 52288   53097   51396
OFF1    55198   53280   54595
OFF1    57463   59341   59911
ON2 65298   64646   63004

What means the collums?

The problem, i don´t own this set by my self so i cant really work on it. But i am interested to solve this code.

fhempy commented 8 years ago

@Icesory I have updated my pull request for pilight (see https://github.com/pilight/pilight/pull/215). You can find all the information in the quigg_gt9000.c file. There are the last findings included. If you have any suggestions how to decode the payload part (see my pull request) I would be very pleased.

Exitras commented 6 years ago

Hi, recently, I also bought those "Silvercrest" 433 MHz plugs which work great with the original remote but not with my Arduino (and ESP8266). I want to control my wallplugs with Amazons Echo Dot. Can someone of you please explain to me how the solution of Icesory works? I would be grateful if you could provide the whole code in C++ for controlling the Silvercrest plug.

Best Exitras