1
0
mirror of https://github.com/seahu/rflink.git synced 2025-12-10 07:57:23 +01:00
Files
rflink_rPi/Plugins/Plugin_015.c
Ondrej Lycka 406093e31d first commit
2017-04-29 03:27:02 +02:00

271 lines
14 KiB
C

//#######################################################################################################
//## This Plugin is only for use with the RFLink software package ##
//## Plugin-15: HomeEasy EU ##
//#######################################################################################################
/*********************************************************************************************\
* Dit protocol zorgt voor ontvangst en verzending HomeEasy EU zenders
* die werken volgens de automatische codering (Ontvangers met leer-knop)
*
* LET OP: GEEN SUPPORT VOOR DIRECTE DIMWAARDES!!!
*
* Author : StuntTeam
* Support : http://sourceforge.net/projects/rflink/
* License : This code is free for use in any open source project when this header is included.
* Usage of any parts of this code in a commercial application is prohibited!
*********************************************************************************************
* Technische informatie:
* Analyses Home Easy Messages and convert these into an eventcode
* Only new EU devices with automatic code system are supported
* Only On / Off status is decoded, no DIM values
* Only tested with Home Easy HE300WEU transmitter, doorsensor and PIR sensor
* Home Easy message structure, by analyzing bitpatterns so far ...
* AAAAAAAAAAA BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB CCCC DD EE FFFFFF G
* 11000111100 10111100011101110010001111100011 1100 10 11 000111 1 HE301EU ON
* 11000111100 10111100011101110010001111100011 1100 01 11 000111 1 HE301EU OFF
* 11000111100 1001 01 11 001011 HE842/844 ON
* 11000111100 01111010011100110010001011000111 1000 11 11 001011 0000000 HE842/844 OFF
* 1000 10 11 000111 HE844 ALLON;
* 1000 01 11 000111 HE844 ALLOFF;
* 11000111100 01111000111101100110010011000111 1000 11 11 000111 0000000
*
* A = Startbits/Preamble,
* B = Address, 32 bits
* C = Unknown, Possibly: Device type
* D = Command, 1 bit only?
* E = Group indicator
* F = Channel 0-15
* G = Stopbit
*
* SAMPLE:
* Pulses=116;Pulses(uSec)=200,1175,125,1175,125,200,150,200,125,200,150,1175,150,1175,150,1175,150,1175,125,200,150,200,150,200,125,1175,150,1175,150,1175,125,1175,150,200,125,200,150,1175,125,1175,150,200,125,1175,125,1175,150,200,150,200,150,1175,150,200,150,1175,150,200,150,1175,150,200,150,200,125,1175,150,200,125,1175,150,1175,125,1175,150,200,125,200,125,200,150,200,125,1175,150,1175,150,1175,150,200,150,200,125,200,150,1175,150,1175,150,1175,150,1175,125,200,150,200,125,1175,125,200,125,1175,150,1150,125;
* HE preamble: 11000111100 (63C) Address: 1111001101100101010010111000011 (79B2A5C3) Stopbits: 0 (0) Commands: 10001111001011 Command: 0 Channel: 1011 Group: 1
* 20;04;HomeEasy;ID=7900b200;SWITCH=0b;CMD=ALLOFF;
*
* Preamble 200,1175,125,1175,125,200,150,200,125,200,150,1175,150,1175,150,1175,150,1175,125,200,150,200,
* Address 150,200,125,1175,150,1175,150,1175,125,1175,150,200,125,200,150,1175,125,1175,150,200,125,1175,125,1175,150,200,150,200,150,1175,150,200,150,1175,150,200,150,1175,150,200,150,200,125,1175,150,200,125,1175,150,1175,125,1175,150,200,125,200,125,200,150,200,125,1175,150,1175,
* Command 150,1175,150,200,150,200,125,200,150,1175,150,1175,150,1175,150,1175,125,200,150,200,125,1175,125,200,125,1175,150,1150, - 125;
\*********************************************************************************************/
#define HomeEasy_PulseLength 116
#define HomeEasy_PULSEMID 500/RAWSIGNAL_SAMPLE_RATE
#ifdef PLUGIN_015
boolean Plugin_015(byte function, char *string) {
if (RawSignal.Number != HomeEasy_PulseLength) return false;
unsigned long preamble = 0L;
unsigned long address = 0L;
unsigned long bitstream = 0L;
byte rfbit =0;
byte command = 0;
byte group = 0;
byte channel = 0;
byte type = 0;
byte temp = 0;
RawSignal.Pulses[0]=0; // undo any Home Easy to Kaku blocking that might be active
//==================================================================================
// convert pulses into bit sections (preamble, address, bitstream)
for(byte x=1;x<=HomeEasy_PulseLength;x=x+2) {
if ((RawSignal.Pulses[x] < HomeEasy_PULSEMID) && (RawSignal.Pulses[x+1] > HomeEasy_PULSEMID))
rfbit = 1;
else
rfbit = 0;
if ( x<=22) preamble = (preamble << 1) | rfbit; // 11 bits preamble
if ((x>=23) && (x<=86)) address = (address << 1) | rfbit; // 32 bits address
if ((x>=87) && (x<=114)) bitstream = (bitstream << 1) | rfbit; // 15 remaining bits
}
//==================================================================================
// To prevent false positives make sure the preamble is correct, it should always be 0x63c
// We compare only 10 bits to compensate for the first bit being seen incorrectly by some receiver modules
if ((preamble & 0x3ff) != 0x23c) return false; // comparing 10 bits is enough to make sure the packet is valid
//==================================================================================
// Prevent repeating signals from showing up
//==================================================================================
if(SignalHash!=SignalHashPrevious || (RepeatingTimer<millis()+1500) || SignalCRC != bitstream ) {
// not seen the RF packet recently
SignalCRC=bitstream;
} else {
// already seen the RF packet recently
return true;
}
//==================================================================================
type = ((bitstream >> 12) & 0x3); // 11b for HE301
channel = (bitstream) & 0x3f;
if (type==3) { // HE301
command = ((bitstream >> 8) & 0x1); // 0=on 1=off (both group and single device)
group = ((bitstream >> 7) & 0x1); // 1=group
} else { // HE800 21c7 = off 22c7=on
temp = ((bitstream >> 8) & 0x7); // 1=group
if (temp < 3) group=1;
command = ((bitstream >> 9) & 0x1); // 0=off 1=on
if (group==1) command=(~command)&1; // reverse bit for group: 1=group off 0=group on
}
// ----------------------------------
// Output
// ----------------------------------
sprintf(pbuffer, "20;%02X;", PKSequenceNumber++); // Node and packet number
Serial.print( pbuffer );
// ----------------------------------
Serial.print("HomeEasy;"); // Label
sprintf(pbuffer, "ID=%08lx;",(address) ); // ID
Serial.print( pbuffer );
sprintf(pbuffer, "SWITCH=%02x;", channel);
Serial.print( pbuffer );
strcpy(pbuffer,"CMD=");
if ( group == 1) {
strcat(pbuffer,"ALL");
}
if ( command == 1) {
strcat(pbuffer,"OFF;");
} else {
strcat(pbuffer,"ON;");
}
Serial.print( pbuffer );
Serial.println();
// ----------------------------------
RawSignal.Repeats = true;
RawSignal.Number=0;
return true;
}
#endif // PLUGIN_015
#ifdef PLUGIN_TX_015
void HomeEasyEU_Send(unsigned long address, unsigned long command);
boolean PluginTX_015(byte function, char *string) {
boolean success=false;
//10;HomeEasy;7900b200;b;ON;
//10;HomeEasy;d900ba00;23;OFF;
//10;HomeEasy;79b2a5c3;b;ON;
//10;HomeEasy;7a7322c7;b;ON;
//01234567890123456789012345
if (strncasecmp(InputBuffer_Serial+3,"HOMEEASY;",9) == 0) { // KAKU Command eg.
if (InputBuffer_Serial[20] != ';') return false;
unsigned long bitstream = 0L;
unsigned long commandcode = 0L;
byte cmd=0;
byte group=0;
// ------------------------------
InputBuffer_Serial[10]=0x30;
InputBuffer_Serial[11]=0x78;
InputBuffer_Serial[20]=0x00;
bitstream=str2int(InputBuffer_Serial+10); // Get Address from hexadecimal value
// ------------------------------
InputBuffer_Serial[19]=0x30;
InputBuffer_Serial[20]=0x78; // Get home from hexadecimal value
commandcode=str2int(InputBuffer_Serial+19); // Get Button number
// ------------------------------
if (InputBuffer_Serial[23] == ';') { // Get command
cmd=str2cmd(InputBuffer_Serial+24);
} else {
cmd=str2cmd(InputBuffer_Serial+23);
}
if (cmd == VALUE_OFF) cmd = 0; // off
if (cmd == VALUE_ON) cmd = 1; // on
if (cmd == VALUE_ALLON) {cmd = 1; group=1;} // allon
if (cmd == VALUE_ALLOFF){cmd = 0; group=1;} // alloff
// ------------------------------
commandcode=commandcode & 0x3f; // get button number
if (group == 1) { // HE8xx: 21xx/22xx HE3xx: 31xx/32xx (off/on) (HE3xx code works for HE8xx)
commandcode=commandcode | 0x30C0; // group
if (cmd == 1) {
commandcode=(commandcode & 0xfdff) | 0x200; // group on > 32cx
} else {
commandcode=commandcode | 0x100; // group off > 31cx
}
} else { // HE8xx: 23cx/25cx HE3xx: 2D4x/2E4x (off/on) (HE3 code works for HE8xx)
commandcode=commandcode | 0x2040; // non-group
if (cmd == 1) {
commandcode=(commandcode & 0xfdff) | 0xe00; // On > 2ECx
} else {
commandcode=commandcode | 0xd00; // Off > 2DCx
}
}
//-----------------------------------------------
HomeEasyEU_Send(bitstream, commandcode);
success=true;
}
return success;
}
void HomeEasyEU_Send(unsigned long address, unsigned long command) {
int fpulse = 275; // Pulse witdh in microseconds
int fretrans = 5; // Number of code retransmissions
uint32_t fdatabit;
uint32_t fdatamask = 0x80000000;
uint32_t fsendbuff;
digitalWrite(PIN_RF_RX_VCC,LOW); // Spanning naar de RF ontvanger uit om interferentie met de zender te voorkomen.
digitalWrite(PIN_RF_TX_VCC,HIGH); // zet de 433Mhz zender aan
delayMicroseconds(TRANSMITTER_STABLE_DELAY); // short delay to let the transmitter become stable (Note: Aurel RTX MID needs 500µS/0,5ms)
for (int nRepeat = 0; nRepeat <= fretrans; nRepeat++) {
// -------------- Send Home Easy preamble (0x63c) - 11 bits
fsendbuff=0x63c;
fdatamask=0x400;
for (int i = 0; i < 11; i++) { // Preamble
// read data bit
fdatabit = fsendbuff & fdatamask; // Get most left bit
fsendbuff = (fsendbuff << 1); // Shift left
if (fdatabit != fdatamask) { // Write 0
digitalWrite(PIN_RF_TX_DATA, HIGH);
delayMicroseconds(fpulse * 1);
digitalWrite(PIN_RF_TX_DATA, LOW);
delayMicroseconds(fpulse * 1);
} else { // Write 1
digitalWrite(PIN_RF_TX_DATA, HIGH);
delayMicroseconds(fpulse * 1);
digitalWrite(PIN_RF_TX_DATA, LOW);
delayMicroseconds(fpulse * 5);
}
}
// -------------- Send Home Easy device Address
fsendbuff=address;
fdatamask=0x80000000;
// Send Address - 32 bits
for (int i = 0; i < 32;i++){ //28;i++){
// read data bit
fdatabit = fsendbuff & fdatamask; // Get most left bit
fsendbuff = (fsendbuff << 1); // Shift left
if (fdatabit != fdatamask) { // Write 0
digitalWrite(PIN_RF_TX_DATA, HIGH);
delayMicroseconds(fpulse * 1);
digitalWrite(PIN_RF_TX_DATA, LOW);
delayMicroseconds(fpulse * 1);
} else { // Write 1
digitalWrite(PIN_RF_TX_DATA, HIGH);
delayMicroseconds(fpulse * 1);
digitalWrite(PIN_RF_TX_DATA, LOW);
delayMicroseconds(fpulse * 5);
}
}
// -------------- Send Home Easy command bits - 14 bits
fsendbuff=command; // 0xFF;
fdatamask=0x2000;
for (int i = 0; i < 14; i++) {
// read data bit
fdatabit = fsendbuff & fdatamask; // Get most left bit
fsendbuff = (fsendbuff << 1); // Shift left
if (fdatabit != fdatamask) { // Write 0
digitalWrite(PIN_RF_TX_DATA, HIGH);
delayMicroseconds(fpulse * 1);
digitalWrite(PIN_RF_TX_DATA, LOW);
delayMicroseconds(fpulse * 1);
} else { // Write 1
digitalWrite(PIN_RF_TX_DATA, HIGH);
delayMicroseconds(fpulse * 1);
digitalWrite(PIN_RF_TX_DATA, LOW);
delayMicroseconds(fpulse * 5);
}
}
// -------------- Send stop
digitalWrite(PIN_RF_TX_DATA, HIGH);
delayMicroseconds(fpulse * 1);
digitalWrite(PIN_RF_TX_DATA, LOW); // and lower the signal
delayMicroseconds(fpulse * 26);
}
delayMicroseconds(TRANSMITTER_STABLE_DELAY); // short delay to let the transmitter become stable (Note: Aurel RTX MID needs 500µS/0,5ms)
digitalWrite(PIN_RF_TX_VCC,LOW); // zet de 433Mhz zender weer uit
digitalWrite(PIN_RF_RX_VCC,HIGH); // Spanning naar de RF ontvanger weer aan.
RFLinkHW();
}
#endif // PLUGIN_TX_015