From 707dd730881cf8e63550f99f89713ee97bd30cbe Mon Sep 17 00:00:00 2001 From: Marc Etcheverry Date: Sun, 15 Oct 2017 12:14:08 -0700 Subject: [PATCH 01/19] Add .gitignore. Remove .DS_Store. --- .DS_Store | Bin 8196 -> 0 bytes .gitignore | 2 ++ 2 files changed, 2 insertions(+) delete mode 100644 .DS_Store create mode 100644 .gitignore diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 93e8d8c8dadbb5568f3a2b065fdd5d3452c110b8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8196 zcmeHMU2GIp6h5aEm>CdmODoGFxM{5*uF#f3t@5*N*9s|38@99*3hV67(2mT`Y<6aM z3$?Lt{sf{g8Z~O-A3uF0k{BOUh$g;h0wEC|Of>3?Z$4?z2hW{5TeoaC@ku4lN$x%O z-gD0V`R=#(=FS2D_T;rTfDiykl(=RqC|g9hou>+^@mp4sMv4b>qAiiOGuaBypdmmY zKp;RMKp;RMK;XZE0NvSKq$>Bmum*X6K!Cvi5&?cbL@03`^YyII-qAss_XHqaOU<58 znehVYh_7S5o)wxbBq%~ji%|5R7%0N2J>vVtd_60)2nX~ZALx&a{tE@Y(W(E4=MESX zI>-YA0t6}%;BWU@*a{P1fV<%Rj>==@wu~K*Yk4;faINdU+g?ZWaT!~yYRgWReG^zZ z%L64i2z`(M8}g8YH0Y_KlTDd+ifq57vZmpX5@r2dYA4^Qy#e}Q6 zd8bFs9rbF4rlcFyhf9FvUY9sQtAenvr$lQ)IdbCd?Nu3=lwh@NvuH^*AV;^euNjp2>W zn;&WK+;!ugRjZj&uQZGnIGm<_sK}8XQ=PPKX@)g%gz&dqtuFW8rNvZ0bAofnr8{E4Q-I5qrAO0r&BJPl}M;bW~wyo&;mpkEy^aDIr8vH+Hw)P zMTtsGlMk6{N;gH*Hl8HdhR0FG6rMyE^H{_wd=6j6*YIt;fERHNKg7%U34SW3Ra2tulcHYA@d}kH zDeDycpK{IUVss4mtx@9tDjjdF+sdlrxzv5mt|(n#`68 zD{+&vn$-$xmqMKEm)SC5-J`_3UlIdRZwbd`iD4P-s*>&^QSJ&6?mFCrZ{a8S8Gc0| znytbRZp8bsiD=e>TX7qNdEB;0m1zr-2cJ-4}St` CSYTcN diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..97efaa5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.DS_Store +*.o From 9985f3facd699c0e0e3097eea2cd292fd2da4c56 Mon Sep 17 00:00:00 2001 From: Marc Etcheverry Date: Sun, 15 Oct 2017 12:14:53 -0700 Subject: [PATCH 02/19] Call disableTransmit() after calling enableTransmit(). --- RFSource/codesend.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/RFSource/codesend.cpp b/RFSource/codesend.cpp index c051cb2..754488a 100644 --- a/RFSource/codesend.cpp +++ b/RFSource/codesend.cpp @@ -76,6 +76,7 @@ int main(int argc, char *argv[]) { mySwitch.setPulseLength(pulseLength); mySwitch.enableTransmit(PIN); mySwitch.send(code, 24); + mySwitch.disableTransmit(); return EXIT_SUCCESS; } From 5e2cbbb9ac140b3622022f5b04a8040ca4d05a2d Mon Sep 17 00:00:00 2001 From: Marc Etcheverry Date: Sun, 15 Oct 2017 12:15:08 -0700 Subject: [PATCH 03/19] Remove old object files. --- RFSource/RCSwitch.o | Bin 13344 -> 0 bytes RFSource/RFSniffer.o | Bin 2556 -> 0 bytes RFSource/codesend.o | Bin 2460 -> 0 bytes 3 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 RFSource/RCSwitch.o delete mode 100644 RFSource/RFSniffer.o delete mode 100644 RFSource/codesend.o diff --git a/RFSource/RCSwitch.o b/RFSource/RCSwitch.o deleted file mode 100644 index 7d88b96a950902e65c8cb205639e72bee9b42dee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13344 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 Date: Sun, 15 Oct 2017 12:15:36 -0700 Subject: [PATCH 04/19] Update RCSwitch, update Makefile and add our own sniffer --- RFSource/Makefile | 22 +- RFSource/RCSwitch.cpp | 780 +++++++++++++++++++++++------------------- RFSource/RCSwitch.h | 131 ++++--- RFSource/sniffer.cpp | 66 ++++ 4 files changed, 587 insertions(+), 412 deletions(-) create mode 100644 RFSource/sniffer.cpp diff --git a/RFSource/Makefile b/RFSource/Makefile index b5f09f2..75da9b0 100644 --- a/RFSource/Makefile +++ b/RFSource/Makefile @@ -1,14 +1,12 @@ -all: send codesend RFSniffer - -send: RCSwitch.o send.o - $(CXX) $(CXXFLAGS) $(LDFLAGS) $+ -o $@ -lwiringPi - +CXXFLAGS = -D RPI +all: codesend sniffer + codesend: RCSwitch.o codesend.o - $(CXX) $(CXXFLAGS) $(LDFLAGS) $+ -o $@ -lwiringPi - -RFSniffer: RCSwitch.o RFSniffer.o - $(CXX) $(CXXFLAGS) $(LDFLAGS) $+ -o $@ -lwiringPi - - + $(CXX) $(CXXFLAGS) $(LDFLAGS) $+ -o $@ -lwiringPi + +sniffer: RCSwitch.o sniffer.o + $(CXX) $(CXXFLAGS) $(LDFLAGS) $+ -o $@ -lwiringPi + clean: - $(RM) *.o send codesend servo RFSniffer \ No newline at end of file + $(RM) *.o codesend sniffer + diff --git a/RFSource/RCSwitch.cpp b/RFSource/RCSwitch.cpp index 67e6e30..6389dbb 100644 --- a/RFSource/RCSwitch.cpp +++ b/RFSource/RCSwitch.cpp @@ -5,9 +5,16 @@ Contributors: - Andre Koehler / info(at)tomate-online(dot)de - Gordeev Andrey Vladimirovich / gordeev(at)openpyro(dot)com - - Skineffect / http://forum.ardumote.com/viewtopic.php?f=2&t=48 + - Skineffect / http://forum.ardumote.com/viewtopic.php?f=2&t=46 + - Dominik Fischer / dom_fischer(at)web(dot)de + - Frank Oltmanns / .(at)gmail(dot)com + - Andreas Steinel / A.(at)gmail(dot)com + - Max Horn / max(at)quendi(dot)de + - Robert ter Vehn / .(at)gmail(dot)com + - Johann Richard / .(at)gmail(dot)com + - Vlad Gheorghe / .(at)gmail(dot)com https://github.com/vgheo - Project home: http://code.google.com/p/rc-switch/ + Project home: https://github.com/sui77/rc-switch/ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -26,47 +33,109 @@ #include "RCSwitch.h" -unsigned long RCSwitch::nReceivedValue = NULL; +#ifdef RaspberryPi + // PROGMEM and _P functions are for AVR based microprocessors, + // so we must normalize these for the ARM processor: + #define PROGMEM + #define memcpy_P(dest, src, num) memcpy((dest), (src), (num)) +#endif + +#ifdef ESP8266 + // interrupt handler and related code must be in RAM on ESP8266, + // according to issue #46. + #define RECEIVE_ATTR ICACHE_RAM_ATTR +#else + #define RECEIVE_ATTR +#endif + + +/* Format for protocol definitions: + * {pulselength, Sync bit, "0" bit, "1" bit} + * + * pulselength: pulse length in microseconds, e.g. 350 + * Sync bit: {1, 31} means 1 high pulse and 31 low pulses + * (perceived as a 31*pulselength long pulse, total length of sync bit is + * 32*pulselength microseconds), i.e: + * _ + * | |_______________________________ (don't count the vertical bars) + * "0" bit: waveform for a data bit of value "0", {1, 3} means 1 high pulse + * and 3 low pulses, total length (1+3)*pulselength, i.e: + * _ + * | |___ + * "1" bit: waveform for a data bit of value "1", e.g. {3,1}: + * ___ + * | |_ + * + * These are combined to form Tri-State bits when sending or receiving codes. + */ +#ifdef ESP8266 +static const RCSwitch::Protocol proto[] = { +#else +static const RCSwitch::Protocol PROGMEM proto[] = { +#endif + { 350, { 1, 31 }, { 1, 3 }, { 3, 1 }, false }, // protocol 1 + { 650, { 1, 10 }, { 1, 2 }, { 2, 1 }, false }, // protocol 2 + { 100, { 30, 71 }, { 4, 11 }, { 9, 6 }, false }, // protocol 3 + { 380, { 1, 6 }, { 1, 3 }, { 3, 1 }, false }, // protocol 4 + { 500, { 6, 14 }, { 1, 2 }, { 2, 1 }, false }, // protocol 5 + { 450, { 23, 1 }, { 1, 2 }, { 2, 1 }, true } // protocol 6 (HT6P20B) +}; + +enum { + numProto = sizeof(proto) / sizeof(proto[0]) +}; + +#if not defined( RCSwitchDisableReceiving ) +unsigned long RCSwitch::nReceivedValue = 0; unsigned int RCSwitch::nReceivedBitlength = 0; unsigned int RCSwitch::nReceivedDelay = 0; unsigned int RCSwitch::nReceivedProtocol = 0; -unsigned int RCSwitch::timings[RCSWITCH_MAX_CHANGES]; int RCSwitch::nReceiveTolerance = 60; +const unsigned int RCSwitch::nSeparationLimit = 4300; +// separationLimit: minimum microseconds between received codes, closer codes are ignored. +// according to discussion on issue #14 it might be more suitable to set the separation +// limit to the same time as the 'low' part of the sync signal for the current protocol. +unsigned int RCSwitch::timings[RCSWITCH_MAX_CHANGES]; +#endif RCSwitch::RCSwitch() { - this->nReceiverInterrupt = -1; this->nTransmitterPin = -1; - RCSwitch::nReceivedValue = NULL; - this->setPulseLength(350); this->setRepeatTransmit(10); - this->setReceiveTolerance(60); this->setProtocol(1); + #if not defined( RCSwitchDisableReceiving ) + this->nReceiverInterrupt = -1; + this->setReceiveTolerance(60); + RCSwitch::nReceivedValue = 0; + #endif } /** * Sets the protocol to send. */ +void RCSwitch::setProtocol(Protocol protocol) { + this->protocol = protocol; +} + +/** + * Sets the protocol to send, from a list of predefined protocols + */ void RCSwitch::setProtocol(int nProtocol) { - this->nProtocol = nProtocol; - if (nProtocol == 1){ - this->setPulseLength(350); - } - else if (nProtocol == 2) { - this->setPulseLength(650); + if (nProtocol < 1 || nProtocol > numProto) { + nProtocol = 1; // TODO: trigger an error, e.g. "bad protocol" ??? } +#ifdef ESP8266 + this->protocol = proto[nProtocol-1]; +#else + memcpy_P(&this->protocol, &proto[nProtocol-1], sizeof(Protocol)); +#endif } /** * Sets the protocol to send with pulse length in microseconds. */ void RCSwitch::setProtocol(int nProtocol, int nPulseLength) { - this->nProtocol = nProtocol; - if (nProtocol == 1){ - this->setPulseLength(nPulseLength); - } - else if (nProtocol == 2) { - this->setPulseLength(nPulseLength); - } + setProtocol(nProtocol); + this->setPulseLength(nPulseLength); } @@ -74,7 +143,7 @@ void RCSwitch::setProtocol(int nProtocol, int nPulseLength) { * Sets pulse length in microseconds */ void RCSwitch::setPulseLength(int nPulseLength) { - this->nPulseLength = nPulseLength; + this->protocol.pulseLength = nPulseLength; } /** @@ -87,9 +156,11 @@ void RCSwitch::setRepeatTransmit(int nRepeatTransmit) { /** * Set Receiving Tolerance */ +#if not defined( RCSwitchDisableReceiving ) void RCSwitch::setReceiveTolerance(int nPercent) { RCSwitch::nReceiveTolerance = nPercent; } +#endif /** @@ -109,6 +180,26 @@ void RCSwitch::disableTransmit() { this->nTransmitterPin = -1; } +/** + * Switch a remote switch on (Type D REV) + * + * @param sGroup Code of the switch group (A,B,C,D) + * @param nDevice Number of the switch itself (1..3) + */ +void RCSwitch::switchOn(char sGroup, int nDevice) { + this->sendTriState( this->getCodeWordD(sGroup, nDevice, true) ); +} + +/** + * Switch a remote switch off (Type D REV) + * + * @param sGroup Code of the switch group (A,B,C,D) + * @param nDevice Number of the switch itself (1..3) + */ +void RCSwitch::switchOff(char sGroup, int nDevice) { + this->sendTriState( this->getCodeWordD(sGroup, nDevice, false) ); +} + /** * Switch a remote switch on (Type C Intertechno) * @@ -152,287 +243,291 @@ void RCSwitch::switchOff(int nAddressCode, int nChannelCode) { } /** + * Deprecated, use switchOn(const char* sGroup, const char* sDevice) instead! * Switch a remote switch on (Type A with 10 pole DIP switches) * * @param sGroup Code of the switch group (refers to DIP switches 1..5 where "1" = on and "0" = off, if all DIP switches are on it's "11111") - * @param nChannelCode Number of the switch itself (1..4) + * @param nChannelCode Number of the switch itself (1..5) */ -void RCSwitch::switchOn(char* sGroup, int nChannel) { - this->sendTriState( this->getCodeWordA(sGroup, nChannel, true) ); +void RCSwitch::switchOn(const char* sGroup, int nChannel) { + const char* code[6] = { "00000", "10000", "01000", "00100", "00010", "00001" }; + this->switchOn(sGroup, code[nChannel]); } /** + * Deprecated, use switchOff(const char* sGroup, const char* sDevice) instead! * Switch a remote switch off (Type A with 10 pole DIP switches) * * @param sGroup Code of the switch group (refers to DIP switches 1..5 where "1" = on and "0" = off, if all DIP switches are on it's "11111") - * @param nChannelCode Number of the switch itself (1..4) + * @param nChannelCode Number of the switch itself (1..5) */ -void RCSwitch::switchOff(char* sGroup, int nChannel) { - this->sendTriState( this->getCodeWordA(sGroup, nChannel, false) ); +void RCSwitch::switchOff(const char* sGroup, int nChannel) { + const char* code[6] = { "00000", "10000", "01000", "00100", "00010", "00001" }; + this->switchOff(sGroup, code[nChannel]); } /** - * Returns a char[13], representing the Code Word to be send. - * A Code Word consists of 9 address bits, 3 data bits and one sync bit but in our case only the first 8 address bits and the last 2 data bits were used. - * A Code Bit can have 4 different states: "F" (floating), "0" (low), "1" (high), "S" (synchronous bit) - * - * +-------------------------------+--------------------------------+-----------------------------------------+-----------------------------------------+----------------------+------------+ - * | 4 bits address (switch group) | 4 bits address (switch number) | 1 bit address (not used, so never mind) | 1 bit address (not used, so never mind) | 2 data bits (on|off) | 1 sync bit | - * | 1=0FFF 2=F0FF 3=FF0F 4=FFF0 | 1=0FFF 2=F0FF 3=FF0F 4=FFF0 | F | F | on=FF off=F0 | S | - * +-------------------------------+--------------------------------+-----------------------------------------+-----------------------------------------+----------------------+------------+ + * Switch a remote switch on (Type A with 10 pole DIP switches) * - * @param nAddressCode Number of the switch group (1..4) - * @param nChannelCode Number of the switch itself (1..4) - * @param bStatus Wether to switch on (true) or off (false) + * @param sGroup Code of the switch group (refers to DIP switches 1..5 where "1" = on and "0" = off, if all DIP switches are on it's "11111") + * @param sDevice Code of the switch device (refers to DIP switches 6..10 (A..E) where "1" = on and "0" = off, if all DIP switches are on it's "11111") + */ +void RCSwitch::switchOn(const char* sGroup, const char* sDevice) { + this->sendTriState( this->getCodeWordA(sGroup, sDevice, true) ); +} + +/** + * Switch a remote switch off (Type A with 10 pole DIP switches) * - * @return char[13] + * @param sGroup Code of the switch group (refers to DIP switches 1..5 where "1" = on and "0" = off, if all DIP switches are on it's "11111") + * @param sDevice Code of the switch device (refers to DIP switches 6..10 (A..E) where "1" = on and "0" = off, if all DIP switches are on it's "11111") */ -char* RCSwitch::getCodeWordB(int nAddressCode, int nChannelCode, boolean bStatus) { - int nReturnPos = 0; - static char sReturn[13]; - - const char* code[5] = { "FFFF", "0FFF", "F0FF", "FF0F", "FFF0" }; - if (nAddressCode < 1 || nAddressCode > 4 || nChannelCode < 1 || nChannelCode > 4) { - return '\0'; - } - for (int i = 0; i<4; i++) { - sReturn[nReturnPos++] = code[nAddressCode][i]; - } - - for (int i = 0; i<4; i++) { - sReturn[nReturnPos++] = code[nChannelCode][i]; - } - - sReturn[nReturnPos++] = 'F'; - sReturn[nReturnPos++] = 'F'; - sReturn[nReturnPos++] = 'F'; - - if (bStatus) { - sReturn[nReturnPos++] = 'F'; - } else { - sReturn[nReturnPos++] = '0'; - } - - sReturn[nReturnPos] = '\0'; - - return sReturn; +void RCSwitch::switchOff(const char* sGroup, const char* sDevice) { + this->sendTriState( this->getCodeWordA(sGroup, sDevice, false) ); } /** - * Like getCodeWord (Type A) + * Returns a char[13], representing the code word to be send. + * */ -char* RCSwitch::getCodeWordA(char* sGroup, int nChannelCode, boolean bStatus) { - int nReturnPos = 0; - static char sReturn[13]; +char* RCSwitch::getCodeWordA(const char* sGroup, const char* sDevice, bool bStatus) { + static char sReturn[13]; + int nReturnPos = 0; - const char* code[6] = { "FFFFF", "0FFFF", "F0FFF", "FF0FF", "FFF0F", "FFFF0" }; + for (int i = 0; i < 5; i++) { + sReturn[nReturnPos++] = (sGroup[i] == '0') ? 'F' : '0'; + } - if (nChannelCode < 1 || nChannelCode > 5) { - return '\0'; + for (int i = 0; i < 5; i++) { + sReturn[nReturnPos++] = (sDevice[i] == '0') ? 'F' : '0'; } - - for (int i = 0; i<5; i++) { - if (sGroup[i] == '0') { - sReturn[nReturnPos++] = 'F'; - } else if (sGroup[i] == '1') { - sReturn[nReturnPos++] = '0'; - } else { - return '\0'; - } + + sReturn[nReturnPos++] = bStatus ? '0' : 'F'; + sReturn[nReturnPos++] = bStatus ? 'F' : '0'; + + sReturn[nReturnPos] = '\0'; + return sReturn; +} + +/** + * Encoding for type B switches with two rotary/sliding switches. + * + * The code word is a tristate word and with following bit pattern: + * + * +-----------------------------+-----------------------------+----------+------------+ + * | 4 bits address | 4 bits address | 3 bits | 1 bit | + * | switch group | switch number | not used | on / off | + * | 1=0FFF 2=F0FF 3=FF0F 4=FFF0 | 1=0FFF 2=F0FF 3=FF0F 4=FFF0 | FFF | on=F off=0 | + * +-----------------------------+-----------------------------+----------+------------+ + * + * @param nAddressCode Number of the switch group (1..4) + * @param nChannelCode Number of the switch itself (1..4) + * @param bStatus Whether to switch on (true) or off (false) + * + * @return char[13], representing a tristate code word of length 12 + */ +char* RCSwitch::getCodeWordB(int nAddressCode, int nChannelCode, bool bStatus) { + static char sReturn[13]; + int nReturnPos = 0; + + if (nAddressCode < 1 || nAddressCode > 4 || nChannelCode < 1 || nChannelCode > 4) { + return 0; } - - for (int i = 0; i<5; i++) { - sReturn[nReturnPos++] = code[ nChannelCode ][i]; + + for (int i = 1; i <= 4; i++) { + sReturn[nReturnPos++] = (nAddressCode == i) ? '0' : 'F'; } - - if (bStatus) { - sReturn[nReturnPos++] = '0'; - sReturn[nReturnPos++] = 'F'; - } else { - sReturn[nReturnPos++] = 'F'; - sReturn[nReturnPos++] = '0'; + + for (int i = 1; i <= 4; i++) { + sReturn[nReturnPos++] = (nChannelCode == i) ? '0' : 'F'; } - sReturn[nReturnPos] = '\0'; + sReturn[nReturnPos++] = 'F'; + sReturn[nReturnPos++] = 'F'; + sReturn[nReturnPos++] = 'F'; + + sReturn[nReturnPos++] = bStatus ? 'F' : '0'; + + sReturn[nReturnPos] = '\0'; return sReturn; } /** * Like getCodeWord (Type C = Intertechno) */ -char* RCSwitch::getCodeWordC(char sFamily, int nGroup, int nDevice, boolean bStatus) { +char* RCSwitch::getCodeWordC(char sFamily, int nGroup, int nDevice, bool bStatus) { static char sReturn[13]; int nReturnPos = 0; - - if ( (byte)sFamily < 97 || (byte)sFamily > 112 || nGroup < 1 || nGroup > 4 || nDevice < 1 || nDevice > 4) { - return '\0'; + + int nFamily = (int)sFamily - 'a'; + if ( nFamily < 0 || nFamily > 15 || nGroup < 1 || nGroup > 4 || nDevice < 1 || nDevice > 4) { + return 0; } - char* sDeviceGroupCode = dec2binWzerofill( (nDevice-1) + (nGroup-1)*4, 4 ); - char familycode[16][5] = { "0000", "F000", "0F00", "FF00", "00F0", "F0F0", "0FF0", "FFF0", "000F", "F00F", "0F0F", "FF0F", "00FF", "F0FF", "0FFF", "FFFF" }; - for (int i = 0; i<4; i++) { - sReturn[nReturnPos++] = familycode[ (int)sFamily - 97 ][i]; - } - for (int i = 0; i<4; i++) { - sReturn[nReturnPos++] = (sDeviceGroupCode[3-i] == '1' ? 'F' : '0'); - } + // encode the family into four bits + sReturn[nReturnPos++] = (nFamily & 1) ? 'F' : '0'; + sReturn[nReturnPos++] = (nFamily & 2) ? 'F' : '0'; + sReturn[nReturnPos++] = (nFamily & 4) ? 'F' : '0'; + sReturn[nReturnPos++] = (nFamily & 8) ? 'F' : '0'; + + // encode the device and group + sReturn[nReturnPos++] = ((nDevice-1) & 1) ? 'F' : '0'; + sReturn[nReturnPos++] = ((nDevice-1) & 2) ? 'F' : '0'; + sReturn[nReturnPos++] = ((nGroup-1) & 1) ? 'F' : '0'; + sReturn[nReturnPos++] = ((nGroup-1) & 2) ? 'F' : '0'; + + // encode the status code sReturn[nReturnPos++] = '0'; sReturn[nReturnPos++] = 'F'; sReturn[nReturnPos++] = 'F'; - if (bStatus) { - sReturn[nReturnPos++] = 'F'; - } else { - sReturn[nReturnPos++] = '0'; - } + sReturn[nReturnPos++] = bStatus ? 'F' : '0'; + sReturn[nReturnPos] = '\0'; return sReturn; } /** - * Sends a Code Word - * @param sCodeWord /^[10FS]*$/ -> see getCodeWord + * Encoding for the REV Switch Type + * + * The code word is a tristate word and with following bit pattern: + * + * +-----------------------------+-------------------+----------+--------------+ + * | 4 bits address | 3 bits address | 3 bits | 2 bits | + * | switch group | device number | not used | on / off | + * | A=1FFF B=F1FF C=FF1F D=FFF1 | 1=0FF 2=F0F 3=FF0 | 000 | on=10 off=01 | + * +-----------------------------+-------------------+----------+--------------+ + * + * Source: http://www.the-intruder.net/funksteckdosen-von-rev-uber-arduino-ansteuern/ + * + * @param sGroup Name of the switch group (A..D, resp. a..d) + * @param nDevice Number of the switch itself (1..3) + * @param bStatus Whether to switch on (true) or off (false) + * + * @return char[13], representing a tristate code word of length 12 */ -void RCSwitch::sendTriState(char* sCodeWord) { - for (int nRepeat=0; nRepeatsendT0(); - break; - case 'F': - this->sendTF(); - break; - case '1': - this->sendT1(); - break; - } - i++; - } - this->sendSync(); +char* RCSwitch::getCodeWordD(char sGroup, int nDevice, bool bStatus) { + static char sReturn[13]; + int nReturnPos = 0; + + // sGroup must be one of the letters in "abcdABCD" + int nGroup = (sGroup >= 'a') ? (int)sGroup - 'a' : (int)sGroup - 'A'; + if ( nGroup < 0 || nGroup > 3 || nDevice < 1 || nDevice > 3) { + return 0; } -} -void RCSwitch::send(unsigned long Code, unsigned int length) { - this->send( this->dec2binWzerofill(Code, length) ); -} + for (int i = 0; i < 4; i++) { + sReturn[nReturnPos++] = (nGroup == i) ? '1' : 'F'; + } -void RCSwitch::send(char* sCodeWord) { - for (int nRepeat=0; nRepeatsend0(); - break; - case '1': - this->send1(); - break; - } - i++; - } - this->sendSync(); + for (int i = 1; i <= 3; i++) { + sReturn[nReturnPos++] = (nDevice == i) ? '1' : 'F'; } -} -void RCSwitch::transmit(int nHighPulses, int nLowPulses) { - boolean disabled_Receive = false; - int nReceiverInterrupt_backup = nReceiverInterrupt; - if (this->nTransmitterPin != -1) { - if (this->nReceiverInterrupt != -1) { - this->disableReceive(); - disabled_Receive = true; - } - digitalWrite(this->nTransmitterPin, HIGH); - delayMicroseconds( this->nPulseLength * nHighPulses); - digitalWrite(this->nTransmitterPin, LOW); - delayMicroseconds( this->nPulseLength * nLowPulses); - if(disabled_Receive){ - this->enableReceive(nReceiverInterrupt_backup); - } - } -} -/** - * Sends a "0" Bit - * _ - * Waveform Protocol 1: | |___ - * _ - * Waveform Protocol 2: | |__ - */ -void RCSwitch::send0() { - if (this->nProtocol == 1){ - this->transmit(1,3); - } - else if (this->nProtocol == 2) { - this->transmit(1,2); - } -} + sReturn[nReturnPos++] = '0'; + sReturn[nReturnPos++] = '0'; + sReturn[nReturnPos++] = '0'; -/** - * Sends a "1" Bit - * ___ - * Waveform Protocol 1: | |_ - * __ - * Waveform Protocol 2: | |_ - */ -void RCSwitch::send1() { - if (this->nProtocol == 1){ - this->transmit(3,1); - } - else if (this->nProtocol == 2) { - this->transmit(2,1); - } -} + sReturn[nReturnPos++] = bStatus ? '1' : '0'; + sReturn[nReturnPos++] = bStatus ? '0' : '1'; + sReturn[nReturnPos] = '\0'; + return sReturn; +} /** - * Sends a Tri-State "0" Bit - * _ _ - * Waveform: | |___| |___ + * @param sCodeWord a tristate code word consisting of the letter 0, 1, F */ -void RCSwitch::sendT0() { - this->transmit(1,3); - this->transmit(1,3); +void RCSwitch::sendTriState(const char* sCodeWord) { + // turn the tristate code word into the corresponding bit pattern, then send it + unsigned long code = 0; + unsigned int length = 0; + for (const char* p = sCodeWord; *p; p++) { + code <<= 2L; + switch (*p) { + case '0': + // bit pattern 00 + break; + case 'F': + // bit pattern 01 + code |= 1L; + break; + case '1': + // bit pattern 11 + code |= 3L; + break; + } + length += 2; + } + this->send(code, length); } /** - * Sends a Tri-State "1" Bit - * ___ ___ - * Waveform: | |_| |_ + * @param sCodeWord a binary code word consisting of the letter 0, 1 */ -void RCSwitch::sendT1() { - this->transmit(3,1); - this->transmit(3,1); +void RCSwitch::send(const char* sCodeWord) { + // turn the tristate code word into the corresponding bit pattern, then send it + unsigned long code = 0; + unsigned int length = 0; + for (const char* p = sCodeWord; *p; p++) { + code <<= 1L; + if (*p != '0') + code |= 1L; + length++; + } + this->send(code, length); } /** - * Sends a Tri-State "F" Bit - * _ ___ - * Waveform: | |___| |_ + * Transmit the first 'length' bits of the integer 'code'. The + * bits are sent from MSB to LSB, i.e., first the bit at position length-1, + * then the bit at position length-2, and so on, till finally the bit at position 0. */ -void RCSwitch::sendTF() { - this->transmit(1,3); - this->transmit(3,1); +void RCSwitch::send(unsigned long code, unsigned int length) { + if (this->nTransmitterPin == -1) + return; + +#if not defined( RCSwitchDisableReceiving ) + // make sure the receiver is disabled while we transmit + int nReceiverInterrupt_backup = nReceiverInterrupt; + if (nReceiverInterrupt_backup != -1) { + this->disableReceive(); + } +#endif + + for (int nRepeat = 0; nRepeat < nRepeatTransmit; nRepeat++) { + for (int i = length-1; i >= 0; i--) { + if (code & (1L << i)) + this->transmit(protocol.one); + else + this->transmit(protocol.zero); + } + this->transmit(protocol.syncFactor); + } + +#if not defined( RCSwitchDisableReceiving ) + // enable receiver again if we just disabled it + if (nReceiverInterrupt_backup != -1) { + this->enableReceive(nReceiverInterrupt_backup); + } +#endif } /** - * Sends a "Sync" Bit - * _ - * Waveform Protocol 1: | |_______________________________ - * _ - * Waveform Protocol 2: | |__________ + * Transmit a single high-low pulse. */ -void RCSwitch::sendSync() { - - if (this->nProtocol == 1){ - this->transmit(1,31); - } - else if (this->nProtocol == 2) { - this->transmit(1,10); - } +void RCSwitch::transmit(HighLow pulses) { + uint8_t firstLogicLevel = (this->protocol.invertedSignal) ? LOW : HIGH; + uint8_t secondLogicLevel = (this->protocol.invertedSignal) ? HIGH : LOW; + + digitalWrite(this->nTransmitterPin, firstLogicLevel); + delayMicroseconds( this->protocol.pulseLength * pulses.high); + digitalWrite(this->nTransmitterPin, secondLogicLevel); + delayMicroseconds( this->protocol.pulseLength * pulses.low); } + +#if not defined( RCSwitchDisableReceiving ) /** * Enable receiving data */ @@ -443,9 +538,13 @@ void RCSwitch::enableReceive(int interrupt) { void RCSwitch::enableReceive() { if (this->nReceiverInterrupt != -1) { - RCSwitch::nReceivedValue = NULL; - RCSwitch::nReceivedBitlength = NULL; + RCSwitch::nReceivedValue = 0; + RCSwitch::nReceivedBitlength = 0; +#if defined(RaspberryPi) // Raspberry Pi wiringPiISR(this->nReceiverInterrupt, INT_EDGE_BOTH, &handleInterrupt); +#else // Arduino + attachInterrupt(this->nReceiverInterrupt, handleInterrupt, CHANGE); +#endif } } @@ -453,19 +552,22 @@ void RCSwitch::enableReceive() { * Disable receiving data */ void RCSwitch::disableReceive() { +#if not defined(RaspberryPi) // Arduino + detachInterrupt(this->nReceiverInterrupt); +#endif // For Raspberry Pi (wiringPi) you can't unregister the ISR this->nReceiverInterrupt = -1; } bool RCSwitch::available() { - return RCSwitch::nReceivedValue != NULL; + return RCSwitch::nReceivedValue != 0; } void RCSwitch::resetAvailable() { - RCSwitch::nReceivedValue = NULL; + RCSwitch::nReceivedValue = 0; } unsigned long RCSwitch::getReceivedValue() { - return RCSwitch::nReceivedValue; + return RCSwitch::nReceivedValue; } unsigned int RCSwitch::getReceivedBitlength() { @@ -481,139 +583,115 @@ unsigned int RCSwitch::getReceivedProtocol() { } unsigned int* RCSwitch::getReceivedRawdata() { - return RCSwitch::timings; + return RCSwitch::timings; +} + +/* helper function for the receiveProtocol method */ +static inline unsigned int diff(int A, int B) { + return abs(A - B); } /** * */ -bool RCSwitch::receiveProtocol1(unsigned int changeCount){ +bool RECEIVE_ATTR RCSwitch::receiveProtocol(const int p, unsigned int changeCount) { +#ifdef ESP8266 + const Protocol &pro = proto[p-1]; +#else + Protocol pro; + memcpy_P(&pro, &proto[p-1], sizeof(Protocol)); +#endif + + unsigned long code = 0; + //Assuming the longer pulse length is the pulse captured in timings[0] + const unsigned int syncLengthInPulses = ((pro.syncFactor.low) > (pro.syncFactor.high)) ? (pro.syncFactor.low) : (pro.syncFactor.high); + const unsigned int delay = RCSwitch::timings[0] / syncLengthInPulses; + const unsigned int delayTolerance = delay * RCSwitch::nReceiveTolerance / 100; - unsigned long code = 0; - unsigned long delay = RCSwitch::timings[0] / 31; - unsigned long delayTolerance = delay * RCSwitch::nReceiveTolerance * 0.01; - - for (int i = 1; i delay-delayTolerance && RCSwitch::timings[i] < delay+delayTolerance && RCSwitch::timings[i+1] > delay*3-delayTolerance && RCSwitch::timings[i+1] < delay*3+delayTolerance) { - code = code << 1; - } else if (RCSwitch::timings[i] > delay*3-delayTolerance && RCSwitch::timings[i] < delay*3+delayTolerance && RCSwitch::timings[i+1] > delay-delayTolerance && RCSwitch::timings[i+1] < delay+delayTolerance) { - code+=1; - code = code << 1; - } else { + /* For protocols that start low, the sync period looks like + * _________ + * _____________| |XXXXXXXXXXXX| + * + * |--1st dur--|-2nd dur-|-Start data-| + * + * The 3rd saved duration starts the data. + * + * For protocols that start high, the sync period looks like + * + * ______________ + * | |____________|XXXXXXXXXXXXX| + * + * |-filtered out-|--1st dur--|--Start data--| + * + * The 2nd saved duration starts the data + */ + const unsigned int firstDataTiming = (pro.invertedSignal) ? (2) : (1); + + for (unsigned int i = firstDataTiming; i < changeCount - 1; i += 2) { + code <<= 1; + if (diff(RCSwitch::timings[i], delay * pro.zero.high) < delayTolerance && + diff(RCSwitch::timings[i + 1], delay * pro.zero.low) < delayTolerance) { + // zero + } else if (diff(RCSwitch::timings[i], delay * pro.one.high) < delayTolerance && + diff(RCSwitch::timings[i + 1], delay * pro.one.low) < delayTolerance) { + // one + code |= 1; + } else { // Failed - i = changeCount; - code = 0; - } - } - code = code >> 1; - if (changeCount > 6) { // ignore < 4bit values as there are no devices sending 4bit values => noise - RCSwitch::nReceivedValue = code; - RCSwitch::nReceivedBitlength = changeCount / 2; - RCSwitch::nReceivedDelay = delay; - RCSwitch::nReceivedProtocol = 1; + return false; + } } - if (code == 0){ - return false; - }else if (code != 0){ - return true; - } - - -} - -bool RCSwitch::receiveProtocol2(unsigned int changeCount){ - - unsigned long code = 0; - unsigned long delay = RCSwitch::timings[0] / 10; - unsigned long delayTolerance = delay * RCSwitch::nReceiveTolerance * 0.01; - - for (int i = 1; i delay-delayTolerance && RCSwitch::timings[i] < delay+delayTolerance && RCSwitch::timings[i+1] > delay*2-delayTolerance && RCSwitch::timings[i+1] < delay*2+delayTolerance) { - code = code << 1; - } else if (RCSwitch::timings[i] > delay*2-delayTolerance && RCSwitch::timings[i] < delay*2+delayTolerance && RCSwitch::timings[i+1] > delay-delayTolerance && RCSwitch::timings[i+1] < delay+delayTolerance) { - code+=1; - code = code << 1; - } else { - // Failed - i = changeCount; - code = 0; - } - } - code = code >> 1; - if (changeCount > 6) { // ignore < 4bit values as there are no devices sending 4bit values => noise - RCSwitch::nReceivedValue = code; - RCSwitch::nReceivedBitlength = changeCount / 2; - RCSwitch::nReceivedDelay = delay; - RCSwitch::nReceivedProtocol = 2; + if (changeCount > 7) { // ignore very short transmissions: no device sends them, so this must be noise + RCSwitch::nReceivedValue = code; + RCSwitch::nReceivedBitlength = (changeCount - 1) / 2; + RCSwitch::nReceivedDelay = delay; + RCSwitch::nReceivedProtocol = p; + return true; } - if (code == 0){ - return false; - }else if (code != 0){ - return true; - } - -} - -void RCSwitch::handleInterrupt() { - - static unsigned int duration; - static unsigned int changeCount; - static unsigned long lastTime; - static unsigned int repeatCount; - - long time = micros(); - duration = time - lastTime; - - if (duration > 5000 && duration > RCSwitch::timings[0] - 200 && duration < RCSwitch::timings[0] + 200) { - repeatCount++; - changeCount--; - - if (repeatCount == 2) { - if (receiveProtocol1(changeCount) == false){ - if (receiveProtocol2(changeCount) == false){ - //failed - } - } - repeatCount = 0; + return false; +} + +void RECEIVE_ATTR RCSwitch::handleInterrupt() { + + static unsigned int changeCount = 0; + static unsigned long lastTime = 0; + static unsigned int repeatCount = 0; + + const long time = micros(); + const unsigned int duration = time - lastTime; + + if (duration > RCSwitch::nSeparationLimit) { + // A long stretch without signal level change occurred. This could + // be the gap between two transmission. + if (diff(duration, RCSwitch::timings[0]) < 200) { + // This long signal is close in length to the long signal which + // started the previously recorded timings; this suggests that + // it may indeed by a a gap between two transmissions (we assume + // here that a sender will send the signal multiple times, + // with roughly the same gap between them). + repeatCount++; + if (repeatCount == 2) { + for(unsigned int i = 1; i <= numProto; i++) { + if (receiveProtocol(i, changeCount)) { + // receive succeeded for protocol i + break; + } + } + repeatCount = 0; + } } changeCount = 0; - } else if (duration > 5000) { - changeCount = 0; } - + + // detect overflow if (changeCount >= RCSWITCH_MAX_CHANGES) { changeCount = 0; repeatCount = 0; } + RCSwitch::timings[changeCount++] = duration; lastTime = time; } - -/** - * Turns a decimal value to its binary representation - */ -char* RCSwitch::dec2binWzerofill(unsigned long Dec, unsigned int bitLength){ - static char bin[64]; - unsigned int i=0; - - while (Dec > 0) { - bin[32+i++] = ((Dec & 1) > 0) ? '1' : '0'; - Dec = Dec >> 1; - } - - for (unsigned int j = 0; j< bitLength; j++) { - if (j >= bitLength - i) { - bin[j] = bin[ 31 + i - (j - (bitLength - i)) ]; - }else { - bin[j] = '0'; - } - } - bin[bitLength] = '\0'; - - return bin; -} - +#endif diff --git a/RFSource/RCSwitch.h b/RFSource/RCSwitch.h index d34d1f9..27e44ec 100644 --- a/RFSource/RCSwitch.h +++ b/RFSource/RCSwitch.h @@ -1,12 +1,17 @@ /* RCSwitch - Arduino libary for remote control outlet switches - Copyright (c) 2011 Suat Özgür. All right reserved. + Copyright (c) 2011 Suat Özgür. All right reserved. Contributors: - Andre Koehler / info(at)tomate-online(dot)de - Gordeev Andrey Vladimirovich / gordeev(at)openpyro(dot)com + - Skineffect / http://forum.ardumote.com/viewtopic.php?f=2&t=46 + - Dominik Fischer / dom_fischer(at)web(dot)de + - Frank Oltmanns / .(at)gmail(dot)com + - Max Horn / max(at)quendi(dot)de + - Robert ter Vehn / .(at)gmail(dot)com - Project home: http://code.google.com/p/rc-switch/ + Project home: https://github.com/sui77/rc-switch/ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -27,30 +32,34 @@ #if defined(ARDUINO) && ARDUINO >= 100 #include "Arduino.h" -#else +#elif defined(ENERGIA) // LaunchPad, FraunchPad and StellarPad specific + #include "Energia.h" +#elif defined(RPI) // Raspberry Pi + #define RaspberryPi + + // Include libraries for RPi: + #include /* memcpy */ + #include /* abs */ #include - #include - #define NULL 0 - #define CHANGE 1 -#ifdef __cplusplus -extern "C"{ +#elif defined(SPARK) + #include "application.h" +#else + #include "WProgram.h" #endif -typedef uint8_t boolean; -typedef uint8_t byte; -#if !defined(NULL) -#endif -#ifdef __cplusplus -} -#endif -#endif +#include + +// At least for the ATTiny X4/X5, receiving has to be disabled due to +// missing libm depencies (udivmodhi4) +#if defined( __AVR_ATtinyX5__ ) or defined ( __AVR_ATtinyX4__ ) +#define RCSwitchDisableReceiving +#endif // Number of maximum High/Low changes per packet. // We can handle up to (unsigned long) => 32 bit * 2 H/L changes per bit + 2 for sync #define RCSWITCH_MAX_CHANGES 67 - class RCSwitch { public: @@ -58,64 +67,88 @@ class RCSwitch { void switchOn(int nGroupNumber, int nSwitchNumber); void switchOff(int nGroupNumber, int nSwitchNumber); - void switchOn(char* sGroup, int nSwitchNumber); - void switchOff(char* sGroup, int nSwitchNumber); + void switchOn(const char* sGroup, int nSwitchNumber); + void switchOff(const char* sGroup, int nSwitchNumber); void switchOn(char sFamily, int nGroup, int nDevice); void switchOff(char sFamily, int nGroup, int nDevice); - - void sendTriState(char* Code); - void send(unsigned long Code, unsigned int length); - void send(char* Code); + void switchOn(const char* sGroup, const char* sDevice); + void switchOff(const char* sGroup, const char* sDevice); + void switchOn(char sGroup, int nDevice); + void switchOff(char sGroup, int nDevice); + + void sendTriState(const char* sCodeWord); + void send(unsigned long code, unsigned int length); + void send(const char* sCodeWord); + #if not defined( RCSwitchDisableReceiving ) void enableReceive(int interrupt); void enableReceive(); void disableReceive(); bool available(); - void resetAvailable(); - + void resetAvailable(); + unsigned long getReceivedValue(); unsigned int getReceivedBitlength(); unsigned int getReceivedDelay(); - unsigned int getReceivedProtocol(); + unsigned int getReceivedProtocol(); unsigned int* getReceivedRawdata(); + #endif void enableTransmit(int nTransmitterPin); void disableTransmit(); void setPulseLength(int nPulseLength); void setRepeatTransmit(int nRepeatTransmit); + #if not defined( RCSwitchDisableReceiving ) void setReceiveTolerance(int nPercent); - void setProtocol(int nProtocol); - void setProtocol(int nProtocol, int nPulseLength); - + #endif + + struct HighLow { + uint8_t high; + uint8_t low; + }; + + struct Protocol { + int pulseLength; + HighLow syncFactor; + HighLow zero; + HighLow one; + /** @brief if true inverts the high and low logic levels in the HighLow structs */ + bool invertedSignal; + }; + + void setProtocol(Protocol protocol); + void setProtocol(int nProtocol); + void setProtocol(int nProtocol, int nPulseLength); + private: - char* getCodeWordB(int nGroupNumber, int nSwitchNumber, boolean bStatus); - char* getCodeWordA(char* sGroup, int nSwitchNumber, boolean bStatus); - char* getCodeWordC(char sFamily, int nGroup, int nDevice, boolean bStatus); - void sendT0(); - void sendT1(); - void sendTF(); - void send0(); - void send1(); - void sendSync(); - void transmit(int nHighPulses, int nLowPulses); - - static char* dec2binWzerofill(unsigned long dec, unsigned int length); - + char* getCodeWordA(const char* sGroup, const char* sDevice, bool bStatus); + char* getCodeWordB(int nGroupNumber, int nSwitchNumber, bool bStatus); + char* getCodeWordC(char sFamily, int nGroup, int nDevice, bool bStatus); + char* getCodeWordD(char group, int nDevice, bool bStatus); + void transmit(HighLow pulses); + + #if not defined( RCSwitchDisableReceiving ) static void handleInterrupt(); - static bool receiveProtocol1(unsigned int changeCount); - static bool receiveProtocol2(unsigned int changeCount); + static bool receiveProtocol(const int p, unsigned int changeCount); int nReceiverInterrupt; + #endif int nTransmitterPin; - int nPulseLength; int nRepeatTransmit; - char nProtocol; + + Protocol protocol; - static int nReceiveTolerance; + #if not defined( RCSwitchDisableReceiving ) + static int nReceiveTolerance; static unsigned long nReceivedValue; static unsigned int nReceivedBitlength; - static unsigned int nReceivedDelay; - static unsigned int nReceivedProtocol; + static unsigned int nReceivedDelay; + static unsigned int nReceivedProtocol; + const static unsigned int nSeparationLimit; + /* + * timings[0] contains sync timing, followed by a number of bits + */ static unsigned int timings[RCSWITCH_MAX_CHANGES]; + #endif }; diff --git a/RFSource/sniffer.cpp b/RFSource/sniffer.cpp new file mode 100644 index 0000000..154ea59 --- /dev/null +++ b/RFSource/sniffer.cpp @@ -0,0 +1,66 @@ +#include +#include +#include +#include + +#include "RCSwitch.h" + +#define DEFAULT_PIN 2 + +void printUsage(char *argv[]) { + printf("Usage: %s [-p (default: %i)].\n", argv[0], DEFAULT_PIN); +} + +int main(int argc, char *argv[]) { + char *argumentPIN = NULL; + + int c; + while ((c = getopt(argc, argv, "p:")) != -1) { + switch (c) { + case 'p': + argumentPIN = optarg; + break; + + case '?': + default: + printUsage(argv); + exit(EXIT_FAILURE); + break; + } + } + + // This PIN is not the first PIN on the Raspberry Pi GPIO header! + // Consult https://projects.drogon.net/raspberry-pi/wiringpi/pins/ + // for more information. + int PIN = DEFAULT_PIN; + + if (argumentPIN != NULL) { + PIN = atoi(argumentPIN); + printf("Listening on PIN: %i\n", PIN); + } + + if (wiringPiSetup() == -1) { + return EXIT_FAILURE; + } + + RCSwitch mySwitch = RCSwitch(); + mySwitch.enableReceive(PIN); // Receiver on INTERRUPT 0 => that is pin #2 + + while(true) { + if (mySwitch.available()) { + int value = mySwitch.getReceivedValue(); + + if (value == 0) { + printf("Unknown encoding"); + } else { + printf("Received %i\n", mySwitch.getReceivedValue() ); + // Show pulse(Depends on your RF outlet device. You may need to change the pulse on codesend.cpp) + printf("Received pulse %i\n", mySwitch.getReceivedDelay() ); + } + + mySwitch.resetAvailable(); + } + } + + return EXIT_SUCCESS; +} From 3640a364607754f7edecbedb693a04fcc1a4e3f1 Mon Sep 17 00:00:00 2001 From: Marc Etcheverry Date: Sun, 15 Oct 2017 12:20:30 -0700 Subject: [PATCH 05/19] Support GET parameters as well as POST. Separate configuration into its own file. Remove delay after each codesend command. --- configuration.inc.php | 35 +++++++++++++++++++++++++++ toggle.php | 55 +++++++++++++------------------------------ 2 files changed, 51 insertions(+), 39 deletions(-) create mode 100644 configuration.inc.php diff --git a/configuration.inc.php b/configuration.inc.php new file mode 100644 index 0000000..ee7385e --- /dev/null +++ b/configuration.inc.php @@ -0,0 +1,35 @@ + array( + "on" => 349491, + "off" => 349500 + ), + "2" => array( + "on" => 349635, + "off" => 349644 + ), + "3" => array( + "on" => 349955, + "off" => 349964 + ), + "4" => array( + "on" => 351491, + "off" => 351500 + ), + "5" => array( + "on" => 357635, + "off" => 357644 + ), +); + +// Path to the codesend binary (current directory is the default) +$codeSendPath = './codesend'; + +// This PIN is not the first PIN on the Raspberry Pi GPIO header! +// Consult https://projects.drogon.net/raspberry-pi/wiringpi/pins/ +// for more information. +$codeSendPIN = "0"; + +// Pulse length depends on the RF outlets you are using. Use RFSniffer to see what pulse length your device uses. +$codeSendPulseLength = "189"; diff --git a/toggle.php b/toggle.php index f7b36b1..16865da 100644 --- a/toggle.php +++ b/toggle.php @@ -2,48 +2,21 @@ header('Content-Type: application/json'); header('Cache-Control: no-cache, must-revalidate'); -// Edit these codes for each outlet -$codes = array( - "1" => array( - "on" => 349491, - "off" => 349500 - ), - "2" => array( - "on" => 349635, - "off" => 349644 - ), - "3" => array( - "on" => 349955, - "off" => 349964 - ), - "4" => array( - "on" => 351491, - "off" => 351500 - ), - "5" => array( - "on" => 357635, - "off" => 357644 - ), -); - -// Path to the codesend binary (current directory is the default) -$codeSendPath = './codesend'; - -// This PIN is not the first PIN on the Raspberry Pi GPIO header! -// Consult https://projects.drogon.net/raspberry-pi/wiringpi/pins/ -// for more information. -$codeSendPIN = "0"; - -// Pulse length depends on the RF outlets you are using. Use RFSniffer to see what pulse length your device uses. -$codeSendPulseLength = "189"; +// Please edit this file with your outlet codes and pulse length +require_once('configuration.inc.php'); if (!file_exists($codeSendPath)) { error_log("$codeSendPath is missing, please edit the script", 0); die(json_encode(array('success' => false))); } -$outletLight = $_POST['outletId']; -$outletStatus = $_POST['outletStatus']; +$outletLight = (!empty($_POST['outletId'])) ? $_POST['outletId'] : $_GET['outletId']; +$outletStatus = (!empty($_POST['outletStatus'])) ? $_POST['outletStatus'] : $_GET['outletStatus']; + +if (empty($outletLight) || empty($outletStatus)) { + error_log('Missing POST paremeters', 0); + die(json_encode(array('success' => false))); +} if ($outletLight == "6") { // 6 is all 5 outlets combined @@ -61,10 +34,14 @@ $codesToToggle = array($codes[$outletLight][$outletStatus]); } +$returnCode = 0; +$output = NULL; foreach ($codesToToggle as $codeSendCode) { - shell_exec($codeSendPath . ' ' . $codeSendCode . ' -p ' . $codeSendPIN . ' -l ' . $codeSendPulseLength); - sleep(1); + exec($codeSendPath . ' ' . $codeSendCode . ' -p ' . $codeSendPIN . ' -l ' . $codeSendPulseLength, $output, $returnCode); + if ($returnCode != 0) { + error_log("Failed to execute $codeSendPath. Output was: " . implode(", ", $output) . ". Code $returnCode"); + die(json_encode(array('success' => false, 'output' => $output))); + } } die(json_encode(array('success' => true))); -?> From 72d70bcb98bf65e834c5a1755c35b348f939a52d Mon Sep 17 00:00:00 2001 From: Marc Etcheverry Date: Sun, 15 Oct 2017 12:21:26 -0700 Subject: [PATCH 06/19] Update codesend and sniffer binaries --- codesend | Bin 18832 -> 20432 bytes sniffer | Bin 0 -> 20436 bytes 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 codesend create mode 100644 sniffer diff --git a/codesend b/codesend old mode 100755 new mode 100644 index 0f40b5eff760492ee3c69e84a73d84b38f97fb5d..3e4803a9eccf1007ac9bdd7f454c696f29e887ca GIT binary patch literal 20432 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
hq3Vr85i&fHwBGmw>v%ewoyl@NcDdFV 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 B?!f>6 diff --git a/sniffer b/sniffer new file mode 100644 index 0000000000000000000000000000000000000000..da02707736bb3769a6ecdff08593911383743a4c GIT binary patch literal 20436 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 Date: Sun, 15 Oct 2017 18:13:34 -0700 Subject: [PATCH 07/19] Add a shared mutex lock so codesend can be called repeatedly and simultaneously to toggle many lights at once. --- RFSource/Makefile | 8 +-- RFSource/codesend.cpp | 36 +++++++++++++ RFSource/shared_mutex.c | 115 ++++++++++++++++++++++++++++++++++++++++ RFSource/shared_mutex.h | 67 +++++++++++++++++++++++ 4 files changed, 222 insertions(+), 4 deletions(-) mode change 100644 => 100755 RFSource/Makefile mode change 100644 => 100755 RFSource/codesend.cpp create mode 100755 RFSource/shared_mutex.c create mode 100755 RFSource/shared_mutex.h diff --git a/RFSource/Makefile b/RFSource/Makefile old mode 100644 new mode 100755 index 75da9b0..d56e089 --- a/RFSource/Makefile +++ b/RFSource/Makefile @@ -1,12 +1,12 @@ CXXFLAGS = -D RPI all: codesend sniffer -codesend: RCSwitch.o codesend.o - $(CXX) $(CXXFLAGS) $(LDFLAGS) $+ -o $@ -lwiringPi +codesend: RCSwitch.o shared_mutex.c codesend.o + $(CXX) $(CXXFLAGS) $(LDFLAGS) $+ -o $@ -lwiringPi -pthread -lrt sniffer: RCSwitch.o sniffer.o - $(CXX) $(CXXFLAGS) $(LDFLAGS) $+ -o $@ -lwiringPi + $(CXX) $(CXXFLAGS) $(LDFLAGS) $+ -o $@ -lwiringPi clean: - $(RM) *.o codesend sniffer + $(RM) *.o codesend sniffer diff --git a/RFSource/codesend.cpp b/RFSource/codesend.cpp old mode 100644 new mode 100755 index 754488a..efadcd6 --- a/RFSource/codesend.cpp +++ b/RFSource/codesend.cpp @@ -4,14 +4,31 @@ #include "RCSwitch.h" +// For serializing access to hardware when called simultaneously +#include +#include +#include "shared_mutex.h" + #define DEFAULT_PIN 0 #define DEFAULT_PULSE_LENGTH 189 +shared_mutex_t mutex; + void printUsage(char *argv[]) { printf("Usage: %s [-p (default: %i)] [-l (default: %i)].\n", argv[0], DEFAULT_PIN, DEFAULT_PULSE_LENGTH); } +void interruptHandler(int signal) { + // None of the pthread functions are async signal safe + printf("Please wait until proper shut down.\n"); +} + int main(int argc, char *argv[]) { + signal(SIGINT, interruptHandler); + signal(SIGHUP, interruptHandler); + signal(SIGQUIT, interruptHandler); + signal(SIGABRT, interruptHandler); + int i; char * argumentPIN = NULL; @@ -59,6 +76,19 @@ int main(int argc, char *argv[]) { // Parse the first parameter to this command as an integer int code = atoi(argv[0]); + // Acquire the shared mutex + // Set a permissive mode since codesend may be executed by www-data and other terminal users. Make the shared memory wide open + mutex = shared_mutex_init("codesend_mutex", S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + if (mutex.ptr == NULL) { + return EXIT_FAILURE; + } + + // if (!mutex.created) { + // printf("A previous codesend instance has already acquired a lock. Waiting!\n"); + // } + + pthread_mutex_lock(mutex.ptr); + if (wiringPiSetup () == -1) { return EXIT_FAILURE; } @@ -78,5 +108,11 @@ int main(int argc, char *argv[]) { mySwitch.send(code, 24); mySwitch.disableTransmit(); + pthread_mutex_unlock(mutex.ptr); + + if (shared_mutex_close(mutex)) { + return EXIT_FAILURE; + } + return EXIT_SUCCESS; } diff --git a/RFSource/shared_mutex.c b/RFSource/shared_mutex.c new file mode 100755 index 0000000..8732ff4 --- /dev/null +++ b/RFSource/shared_mutex.c @@ -0,0 +1,115 @@ +#include "shared_mutex.h" +#include // errno, ENOENT +#include // O_RDWR, O_CREATE +#include // NAME_MAX +#include // shm_open, shm_unlink, mmap, munmap, + // PROT_READ, PROT_WRITE, MAP_SHARED, MAP_FAILED +#include // ftruncate, close +#include // perror +#include // malloc, free +#include // strcpy + +shared_mutex_t shared_mutex_init(const char *name, mode_t mode) { + shared_mutex_t mutex = {NULL, 0, NULL, 0}; + errno = 0; + + // Open existing shared memory object, or create one. + // Two separate calls are needed here, to mark fact of creation + // for later initialization of pthread mutex. + mutex.shm_fd = shm_open(name, O_RDWR, mode); + if (errno == ENOENT) { + mutex.shm_fd = shm_open(name, O_RDWR|O_CREAT, mode); + mutex.created = 1; + } + if (mutex.shm_fd == -1) { + perror("shm_open"); + return mutex; + } + + // Change permissions of shared memory, so every body can access it. Avoiding the umask of shm_open + if (fchmod(mutex.shm_fd, mode) != 0) { + perror("fchmod"); + } + + // Truncate shared memory segment so it would contain + // pthread_mutex_t. + if (ftruncate(mutex.shm_fd, sizeof(pthread_mutex_t)) != 0) { + perror("ftruncate"); + return mutex; + } + + // Map pthread mutex into the shared memory. + void *addr = mmap( + NULL, + sizeof(pthread_mutex_t), + PROT_READ|PROT_WRITE, + MAP_SHARED, + mutex.shm_fd, + 0 + ); + if (addr == MAP_FAILED) { + perror("mmap"); + return mutex; + } + pthread_mutex_t *mutex_ptr = (pthread_mutex_t *)addr; + + // If shared memory was just initialized - + // initialize the mutex as well. + if (mutex.created) { + pthread_mutexattr_t attr; + if (pthread_mutexattr_init(&attr)) { + perror("pthread_mutexattr_init"); + return mutex; + } + if (pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED)) { + perror("pthread_mutexattr_setpshared"); + return mutex; + } + if (pthread_mutex_init(mutex_ptr, &attr)) { + perror("pthread_mutex_init"); + return mutex; + } + } + mutex.ptr = mutex_ptr; + mutex.name = (char *)malloc(NAME_MAX+1); + strcpy(mutex.name, name); + return mutex; +} + +int shared_mutex_close(shared_mutex_t mutex) { + if (munmap((void *)mutex.ptr, sizeof(pthread_mutex_t))) { + perror("munmap"); + return -1; + } + mutex.ptr = NULL; + if (close(mutex.shm_fd)) { + perror("close"); + return -1; + } + mutex.shm_fd = 0; + free(mutex.name); + return 0; +} + +int shared_mutex_destroy(shared_mutex_t mutex) { + if ((errno = pthread_mutex_destroy(mutex.ptr))) { + perror("pthread_mutex_destroy"); + return -1; + } + if (munmap((void *)mutex.ptr, sizeof(pthread_mutex_t))) { + perror("munmap"); + return -1; + } + mutex.ptr = NULL; + if (close(mutex.shm_fd)) { + perror("close"); + return -1; + } + mutex.shm_fd = 0; + if (shm_unlink(mutex.name)) { + perror("shm_unlink"); + return -1; + } + free(mutex.name); + return 0; +} diff --git a/RFSource/shared_mutex.h b/RFSource/shared_mutex.h new file mode 100755 index 0000000..b700400 --- /dev/null +++ b/RFSource/shared_mutex.h @@ -0,0 +1,67 @@ +#ifndef SHARED_MUTEX_H +#define SHARED_MUTEX_H + +#include + +#include // pthread_mutex_t, pthread_mutexattr_t, + // pthread_mutexattr_init, pthread_mutexattr_setpshared, + // pthread_mutex_init, pthread_mutex_destroy + +// Structure of a shared mutex. +typedef struct shared_mutex_t { + pthread_mutex_t *ptr; // Pointer to the pthread mutex and + // shared memory segment. + int shm_fd; // Descriptor of shared memory object. + char* name; // Name of the mutex and associated + // shared memory object. + int created; // Equals 1 (true) if initialization + // of this structure caused creation + // of a new shared mutex. + // Equals 0 (false) if this mutex was + // just retrieved from shared memory. +} shared_mutex_t; + +// Initialize a new shared mutex with given `name`. If a mutex +// with such name exists in the system, it will be loaded. +// Otherwise a new mutes will by created. +// +// In case of any error, it will be printed into the standard output +// and the returned structure will have `ptr` equal `NULL`. +// `errno` wil not be reset in such case, so you may used it. +// +// **NOTE:** In case when the mutex appears to be uncreated, +// this function becomes *non-thread-safe*. If multiple threads +// call it at one moment, there occur several race conditions, +// in which one call might recreate another's shared memory +// object or rewrite another's pthread mutex in the shared memory. +// There is no workaround currently, except to run first +// initialization only before multi-threaded or multi-process +// functionality. +shared_mutex_t shared_mutex_init(const char *name, mode_t mode); + +// Close access to the shared mutex and free all the resources, +// used by the structure. +// +// Returns 0 in case of success. If any error occurs, it will be +// printed into the standard output and the function will return -1. +// `errno` wil not be reset in such case, so you may used it. +// +// **NOTE:** It will not destroy the mutex. The mutex would not +// only be available to other processes using it right now, +// but also to any process which might want to use it later on. +// For complete desctruction use `shared_mutex_destroy` instead. +// +// **NOTE:** It will not unlock locked mutex. +int shared_mutex_close(shared_mutex_t mutex); + +// Close and destroy shared mutex. +// Any open pointers to it will be invalidated. +// +// Returns 0 in case of success. If any error occurs, it will be +// printed into the standard output and the function will return -1. +// `errno` wil not be reset in such case, so you may used it. +// +// **NOTE:** It will not unlock locked mutex. +int shared_mutex_destroy(shared_mutex_t mutex); + +#endif // SHARED_MUTEX_H From 7054eb04c8f2534c34cd82111ee3945b49cbb73b Mon Sep 17 00:00:00 2001 From: Marc Etcheverry Date: Sun, 15 Oct 2017 20:30:30 -0700 Subject: [PATCH 08/19] Remove old send.cpp file --- RFSource/send.cpp | 39 --------------------------------------- 1 file changed, 39 deletions(-) delete mode 100644 RFSource/send.cpp diff --git a/RFSource/send.cpp b/RFSource/send.cpp deleted file mode 100644 index 076e77c..0000000 --- a/RFSource/send.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - Usage: ./send - Command is 0 for OFF and 1 for ON - */ - -#include "RCSwitch.h" -#include -#include - -int main(int argc, char *argv[]) { - - /* - output PIN is hardcoded for testing purposes - see https://projects.drogon.net/raspberry-pi/wiringpi/pins/ - for pin mapping of the raspberry pi GPIO connector - */ - int PIN = 0; - char* systemCode = argv[1]; - int unitCode = atoi(argv[2]); - int command = atoi(argv[3]); - - if (wiringPiSetup () == -1) return 1; - printf("sending systemCode[%s] unitCode[%i] command[%i]\n", systemCode, unitCode, command); - RCSwitch mySwitch = RCSwitch(); - mySwitch.enableTransmit(PIN); - - switch(command) { - case 1: - mySwitch.switchOn(systemCode, unitCode); - break; - case 0: - mySwitch.switchOff(systemCode, unitCode); - break; - default: - printf("command[%i] is unsupported\n", command); - return -1; - } - return 0; -} From bf6b2b12e128f932728b49ad90754e0ac245afe5 Mon Sep 17 00:00:00 2001 From: Marc Etcheverry Date: Mon, 16 Oct 2017 07:11:50 -0700 Subject: [PATCH 09/19] Only fchmod shm on creation, not every time shm is opened --- RFSource/shared_mutex.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/RFSource/shared_mutex.c b/RFSource/shared_mutex.c index 8732ff4..0d1a1fe 100755 --- a/RFSource/shared_mutex.c +++ b/RFSource/shared_mutex.c @@ -20,17 +20,16 @@ shared_mutex_t shared_mutex_init(const char *name, mode_t mode) { if (errno == ENOENT) { mutex.shm_fd = shm_open(name, O_RDWR|O_CREAT, mode); mutex.created = 1; + // Change permissions of shared memory, so every body can access it. Avoiding the umask of shm_open + if (fchmod(mutex.shm_fd, mode) != 0) { + perror("fchmod"); + } } if (mutex.shm_fd == -1) { perror("shm_open"); return mutex; } - // Change permissions of shared memory, so every body can access it. Avoiding the umask of shm_open - if (fchmod(mutex.shm_fd, mode) != 0) { - perror("fchmod"); - } - // Truncate shared memory segment so it would contain // pthread_mutex_t. if (ftruncate(mutex.shm_fd, sizeof(pthread_mutex_t)) != 0) { From 0212577e4bf03378b68d22206112aa09a63f0188 Mon Sep 17 00:00:00 2001 From: Marc Etcheverry Date: Tue, 17 Oct 2017 17:15:31 -0700 Subject: [PATCH 10/19] Remove legacy RFSniffer --- RFSniffer | Bin 18144 -> 0 bytes RFSource/RFSniffer.cpp | 48 ----------------------------------------- 2 files changed, 48 deletions(-) delete mode 100755 RFSniffer delete mode 100644 RFSource/RFSniffer.cpp diff --git a/RFSniffer b/RFSniffer deleted file mode 100755 index 285328c12243e29e0f32f20f62bc9f2426f5de62..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18144 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 diff --git a/RFSource/RFSniffer.cpp b/RFSource/RFSniffer.cpp deleted file mode 100644 index 6298526..0000000 --- a/RFSource/RFSniffer.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include "RCSwitch.h" -#include -#include - - -RCSwitch mySwitch; - - - -int main(int argc, char *argv[]) { - - // This pin is not the first pin on the RPi GPIO header! - // Consult https://projects.drogon.net/raspberry-pi/wiringpi/pins/ - // for more information. - int PIN = 2; - - if(wiringPiSetup() == -1) - return 0; - - mySwitch = RCSwitch(); - mySwitch.enableReceive(PIN); // Receiver on inerrupt 0 => that is pin #2 - - - while(1) { - - if (mySwitch.available()) { - - int value = mySwitch.getReceivedValue(); - - if (value == 0) { - printf("Unknown encoding"); - } else { - printf("Received %i\n", mySwitch.getReceivedValue() ); - //Show pulse(Depends on your RF outlet device. You may need to change the pulse on codesend.cpp) - printf("Received pulse %i\n", mySwitch.getReceivedDelay() ); - } - - mySwitch.resetAvailable(); - - } - - - } - - exit(0); - - -} From bb09f2c835b2f1c1e0faf43c0f9c32cdd0887f95 Mon Sep 17 00:00:00 2001 From: Marc Etcheverry Date: Tue, 17 Oct 2017 21:26:42 -0700 Subject: [PATCH 11/19] Remove .DS_Store file --- RFSource/.DS_Store | Bin 6148 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 RFSource/.DS_Store diff --git a/RFSource/.DS_Store b/RFSource/.DS_Store deleted file mode 100644 index 5008ddfcf53c02e82d7eee2e57c38e5672ef89f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 Date: Tue, 17 Oct 2017 21:33:05 -0700 Subject: [PATCH 12/19] Make codesend and sniffer be symbolic links to the source directory so upon recompilation there aren't two copies --- RFSource/codesend | Bin 0 -> 25828 bytes RFSource/sniffer | Bin 0 -> 20436 bytes codesend | Bin 20432 -> 25828 bytes sniffer | Bin 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100755 RFSource/codesend create mode 100755 RFSource/sniffer mode change 100644 => 100755 codesend mode change 100644 => 100755 sniffer diff --git a/RFSource/codesend b/RFSource/codesend new file mode 100755 index 0000000000000000000000000000000000000000..7ed2023129663c9a87cd1bfd1a502f5fb3cf8276 GIT binary patch literal 25828 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 s932tA=a%1VSOt-ljYMQGB5?NQ>@20jK|aB>(^b literal 0 HcmV?d00001 diff --git a/RFSource/sniffer b/RFSource/sniffer new file mode 100755 index 0000000000000000000000000000000000000000..da02707736bb3769a6ecdff08593911383743a4c GIT binary patch literal 20436 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 s932tA=a%1VSOt-ljYMQGB5?NQ>@20jK|aB>(^b delta 6729 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 diff --git a/sniffer b/sniffer old mode 100644 new mode 100755 From 80c0b58be9c3f02ad1966f95d36c9c2e9900d612 Mon Sep 17 00:00:00 2001 From: Marc Etcheverry Date: Tue, 17 Oct 2017 22:14:23 -0700 Subject: [PATCH 13/19] Integer checking for arguments and need to specify PIN on sniffer utility --- RFSource/Makefile | 4 ++-- RFSource/RFOutlet.c | 26 ++++++++++++++++++++++++++ RFSource/RFOutlet.h | 1 + RFSource/codesend | Bin 25828 -> 25932 bytes RFSource/codesend.cpp | 23 +++++++++++++++++------ RFSource/sniffer | Bin 20436 -> 20624 bytes RFSource/sniffer.cpp | 11 +++++++++-- codesend | Bin 25828 -> 25932 bytes sniffer | Bin 20436 -> 20624 bytes 9 files changed, 55 insertions(+), 10 deletions(-) create mode 100755 RFSource/RFOutlet.c create mode 100755 RFSource/RFOutlet.h mode change 100644 => 100755 RFSource/sniffer.cpp diff --git a/RFSource/Makefile b/RFSource/Makefile index d56e089..a9d3d79 100755 --- a/RFSource/Makefile +++ b/RFSource/Makefile @@ -1,10 +1,10 @@ CXXFLAGS = -D RPI all: codesend sniffer -codesend: RCSwitch.o shared_mutex.c codesend.o +codesend: RCSwitch.o shared_mutex.c RFOutlet.c codesend.o $(CXX) $(CXXFLAGS) $(LDFLAGS) $+ -o $@ -lwiringPi -pthread -lrt -sniffer: RCSwitch.o sniffer.o +sniffer: RCSwitch.o RFOutlet.c sniffer.o $(CXX) $(CXXFLAGS) $(LDFLAGS) $+ -o $@ -lwiringPi clean: diff --git a/RFSource/RFOutlet.c b/RFSource/RFOutlet.c new file mode 100755 index 0000000..47b4fe4 --- /dev/null +++ b/RFSource/RFOutlet.c @@ -0,0 +1,26 @@ +#include +#include +#include + +bool parseStringToInt(const char *input, int *value, int base) { + bool success = true; + char *endptr; + errno = 0; + long longNumber = strtol(input, &endptr, base); + + if (longNumber < INT_MIN || INT_MAX < longNumber) { + errno = ERANGE; + } + + if (*endptr == longNumber || *endptr != '\0') { + errno = EINVAL; + } + + if (errno != 0) { + success = false; + } else { + *value = longNumber; + } + + return success; +} diff --git a/RFSource/RFOutlet.h b/RFSource/RFOutlet.h new file mode 100755 index 0000000..7a544ac --- /dev/null +++ b/RFSource/RFOutlet.h @@ -0,0 +1 @@ +bool parseStringToInt(const char *input, int *value, int base); diff --git a/RFSource/codesend b/RFSource/codesend index 7ed2023129663c9a87cd1bfd1a502f5fb3cf8276..906d1a159673124a2c5d2b55cd0312c035560c9b 100755 GIT binary patch delta 6313 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 delta 5895 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 #include #include +#include #include "RCSwitch.h" - +#include "RFOutlet.h" // For serializing access to hardware when called simultaneously -#include -#include #include "shared_mutex.h" #define DEFAULT_PIN 0 @@ -23,6 +22,7 @@ void interruptHandler(int signal) { printf("Please wait until proper shut down.\n"); } + int main(int argc, char *argv[]) { signal(SIGINT, interruptHandler); signal(SIGHUP, interruptHandler); @@ -59,7 +59,10 @@ int main(int argc, char *argv[]) { int PIN = DEFAULT_PIN; if (argumentPIN != NULL) { - PIN = atoi(argumentPIN); + if (!parseStringToInt(argumentPIN, &PIN, 10)) { + perror("Invalid PIN"); + return EXIT_FAILURE; + } } /* Now set the values of "argc" and "argv" to the values after the @@ -74,7 +77,12 @@ int main(int argc, char *argv[]) { argv += optind; // Parse the first parameter to this command as an integer - int code = atoi(argv[0]); + int code = 0; + + if (!parseStringToInt(argv[0], &code, 10)) { + perror("Invalid code"); + return EXIT_FAILURE; + } // Acquire the shared mutex // Set a permissive mode since codesend may be executed by www-data and other terminal users. Make the shared memory wide open @@ -97,7 +105,10 @@ int main(int argc, char *argv[]) { int pulseLength = DEFAULT_PULSE_LENGTH; if (argumentPulseLength != NULL) { - pulseLength = atoi(argumentPulseLength); + if (!parseStringToInt(argumentPulseLength, &pulseLength, 10)) { + perror("Invalid pulse length"); + return EXIT_FAILURE; + } } printf("Sending Code: %i. PIN: %i. Pulse Length: %i\n", code, PIN, pulseLength); diff --git a/RFSource/sniffer b/RFSource/sniffer index da02707736bb3769a6ecdff08593911383743a4c..5ca467455ef3ff352a631119066e056865660a41 100755 GIT binary patch delta 5945 zcmbtYdvKK16+d?$VUujgCfS5dcFAs@gf@}|b}%@hCW;!GB?Qe>C@6^pNopWzTq#bO zen@d9&Y%V_I%&l*XzXMh+d-FBZLwx7DpH-MRxQ%hk>DyKXsA|#ukG)AkL0rd_Ricr z_jk^@=bn4+>wNpxqhjEI81OBOx&%dt=(#5RILH~H5T#QU1*w<>QSWmVkW~o1jzMK? z?}~M4dn$?cRPKGU$Qgsq2YX-pr}p&N(Y$xoUz>gG=J^*q&Rbn0yB=)LfqojQ%dD9@ z(WnoeRp=ZSMIQNJMYCL#^gC$aM}JcG*NPCHf;lKn`Pll`URS8VVf@ZP$2~kk&fBR z<#L5R=#F1&tIF;^ESQD8+N~Kv5+V1#m?(>#c z7->rB>XY*wLD^{c#Md~gM1Ak3zP_G5YQLqYFGjt6U0Y+f((SRnSWh=?*Z|qqo(rdUsJjJ9mrva$D0LbJVZv;2*7mtP>7Hmr~xzZ_XYn>lF9hBUu;Lf(`X z)P8Gv(t?oWJB-kHu`+Jp0>s0^6f5XuT8u?wij@j5#VUuGVl~T|VzsN7x{0cpW)X#% z&LxU4%_pj5>L;pWT0oW9NN5xy?o6>o8kxe8DAOQzUHxSrUng^B&CzyO!Pi&rpU6G7 zXJYr%;e^%Rp|oR4yIW~@DDCx1yH#mNmG*L_U1zkL^?@Ubpjv5{EA4>N_9|_+(ssyy z&#IaIW-|H7AU11DiJ;mtS>!5qcFqHo%UtuE8xesv+2va7_7 zY5L>d4d_fXbkZ@_G(r6@oF0K8`IOry>oX2H)}xCYDhx<(rq}LDCguIJ^W*iIZ8k@F zIn?U1TIE!h$5vh*&zSwG5WD4SZ(iK(84zM${E?ivO$^6Zdy_&Oimxunwu_(1_QD!* zo7`J?f8me5zI5D94AqS~DVG*)maTrTJX90_twybv9=}hHfCnmK@-F{8u^qo&`GSA5 z_?N5*TrQ5qZwkz^UB>QjhZ*)fc=so(EwjDAF;r^2>|@8ldnY_&D<>|G?=5Z;-lI5D zuX{-E_Bz@}Q02inK23y&PC3I(iBlKhYG~*r0aJKa!V_+q2!;F!yJzU6kNk;eA$LUC9 z=$8p+cwNFS&u8Yz@j{Puh1|Iha(86~>&j(is5pP5k`LE5cj!?^r=J5L_}2IoAD^;_k;i-K46D_ReNYhjydby$%%L2ku>Gd{-HAy+Ie&h0cq zW3h+I8O4xyD46BersD(3*ggAF zeUE}!9#e1=X?TPc#uMnf8;>#XcY!3EJ9Kzv48DoxK1I$m>Qv;c@5-Ig{~FEV6n(cM zZ^Za?*gMmq0?|E`(qUAQ^8kmj6^vp;WK_W{-(Pg8d_=)4cO%8N`fEG`kHTPuIt8=5 zUcoHyR4~iC70mK|3TFABf>}N~gEf84kIXRike^jB8<KMt?2joNpmj#}d~TQa>1+kQt0ZiUV^}W?|g{#Q;0d7?K&aMSAeohh}WEsI$_- zIdl%Dtm2^aNtV}{mn7d?y6;G#jbhvZ(G)y1eSnPp-8*CdM%@7C;HrVZ^oh=*izyE9 zfVGO89U4$D%LmKkvD)I?{^@aY$%*_4m-kn-MIuk;FAZuzFs2q5#sw8n74W2q`ITG> zd{)6xU@~tGf!CGC;Rn(vZhg^rD469t6?_Z&@0=rOKlr(nrO|dUc-J72V+QR9=46`} zEe8kp1z`UA;Nrn;dIZ=i{FuK3%(=g%KLtF7nW;i-DvO|b6<1dkASQ!HUfpHJyK16^IBFi5J=DTv(jL08>`7*CJsv1|163F6YPii)!-Su4MqSVvj)7vh0lNU$!Gaz+`%mDfWZF_d>LDtHU!LHjxeFm za0xJ9byd*i{%e5)J`89^Y%4I|wblG;u!01`S`)^@z~#7qi!=Ke*mLRS<^Ab=DFno$AMe$8Vs46^jl!Q0NXG) zM=T2w;v4+1iK~oM8OWGmBk-tl%5DYr`0)*6T@-hxbT|Oa@1-@Pmr~?o3JzhAv%vgM z3U4}g=o?_pv5ZaVqq+D%i5AXm!g}CQO*yCQz~H|ctX+F2D{#hO&Ug^mDjf3PD>wvv zBn7_*?8-)j%m|B2BWbhlf%(AksULi5%eem9Rd>X?H^mlgl!=DpX~rLYa%{OzzIN4D zX~utn@mH^|b`<`2;ga6=zS}q55W|0hn_GKUY>l-vZEWf4lIO46ke%|+AX|v9Ykbuv z%bWIyartypFoQpZ26!9U9V~E|7k?s>BhGj<|)rdgBg5;qr7kYvS?*-8sBO7 zEcn67(sX_ShRcY`WY@}I8fTtI%jJC#7=KY?ugm8l;HMMM<$EiSiB?$5lZTt#PCgc` z@{Q&)^Ix(5HqR4na_*{m;$C^ps(D$5v7-*+y9)m~(gX6&RsOW@D~Xn5%3rT4bw2h( JqI^s??|+8#cnkml delta 5653 zcmbVQe{j^r6@Pm_!d-HgT#^HlT+CfAKRCybTp-rK#1at4AW48}TI2YmAVE<swh^f(a|uKn`=EV%NcQuj-f4|o z<_e3l(} zbzr?XJJB)^fsw^AFX&^S0CEKRr`7jh?VR*$`D9kukoGWIVAoU_#`XoVem>A?Sl4%Nl=Rl3%%HZ2u(KGM3Qz$25Ms#`kIbMvdQ~@!cA~S}yX`<$jb(oveft$0C9b zm&*q|W$q(01hvR#Ju}?bVeFmqBhPF%Pk*QMdoK~!%Q@bs#B%vh?^D5>P?;z(>Ka}= zMtuj5H=rT8++QRIvtJY)az)N;k(1n+bGO5BAS!cnZ+0E96_VR?j|kD5Torgqh%HHP zLDC@xk_Uq+AqJBNr{y`tz4C+NI&p{mzIa>lwdXGEW;u-MLf$N&F1ZD!ycsH#kx;40 zU1EQ`PL3t>w~ftBeqXj&1P@_9z7N0UYKOtUhAf*)ie$XpSMbhv7g{?M zmF?waQQ9|*=Xb^n`?Y=PZk}kBp0c~U7OtyBNt?LXVMq427hFtY@ zn|v580;}6Zfk8koQOB+{#(W4VBHp*ncc#aMXDDUn#?tN*NQNjDugK3iFp7V{S*5F!{}(2=iu?<>Qc#)E`o* zbqi6R0_Au-0h*O1WPf%2BXQrHBJ}rvW!V;g%V4uOISJm1#O88xnnvSXN5>ZC6C3e$ z60>PUY%nLMd74`Tu`mxdeZo4;lOBN|)^c(ZqC7SU@x_Fb)0{M(HidJ|^7tgSt_dyh zIZK~UBJ0v(VV+B*DmhkvV}2`#0wgElltAi~%VsT^uR0@i)`C*L@mML}!~ra$l`OgH zobM>C-zrCEg^f~8YbQz-cBoc0`C`b`ErV}6jMWecw~)QSD!J(E6w8D5lqmfgdkR?p z1d%jmmmAGm9|A@ztZeAg~E;UA@ycM*x<-+r9659EMqoB*pttZ-b%%0IiCPl zvP|@NRefvmx-)RIw%9x+Jr~Lis?1I|V6Kyf*^tv3X89Qnvs}3*Z(qg<1VbzN%{kns zVU~Mxb-4jY(F&f1tQQ9rhZ2EX9#=S%m#*+vuv;`a8+2Ziv;IJSTK^o_feihGCT~Ii zv^1EmP=(nY%&5?z$+?52a0M$_Bka&H%i|>%%9}LI@`Q#B9>G4XfE9){%<>}|X8Cyy zvz$Wd4p|=4Fw1K+%<_&jHq15ZOc$6_zEQ*6z-A3|1N$}1@<9!^^9%wvqFgzAS6SM? zYa!>m2w&s{8O79x0=}$R1;vyE<_n9$rU6<5Y`~}Cbc18iSBZlO%ZIdG#q}pNeU?|^ zCTS+aj$V<;ZDM)x@kyL-MK4vs)*mcS8}LtXP0k&bP8wwS3}0tCUCBWi;cYUh z5m1%tpn%SD2R7!Dk{di-t9qSE9@#c0Yy@#PJ7bp$JS8szo|x1sq*~xp8lDeKb~F(< zkJ)T>P+?b^y~HMivd@&)X!sh`4^9^}fO-YwH)t&i*pq6k0_q3m%PB7;KiOVjx!qv^ z5%v$jd_`9Be=tULiQDz3dvNyH`Vr`#g`CeOOFxgiV44tJR-5{UpDIysq*xXBX#p_5 z83r(wu#m0-K8z0dmjL72fmP!B$9)-iE3p2;+zG6Xha2IeJWyLkzZ0&_sOrrb}bfqShbF`$q~ zLHrWw!U$UJ250gw5GgU~@_MB;g7VpnwCe>fksGQg@*O+=ZUu2C;@4Z2dn1t6jlP^=IG&oLD*ODPWZ% z%%DA$ctBHtxjy%gBeZ!-zp5x%z33H({A}^V;)q<^8qVey4IiW< zLhfoU^YVjcHO$>D54MKA{G7>Rzn9~!VK+Z!7D{hhg`1x-n`M1lg_mDqytOvS8`{Ed zc2}R=gmUYN1^hS#nKtIFJjG? p;z@*mTeJ #include +#include "RFOutlet.h" #include "RCSwitch.h" #define DEFAULT_PIN 2 @@ -35,9 +36,15 @@ int main(int argc, char *argv[]) { int PIN = DEFAULT_PIN; if (argumentPIN != NULL) { - PIN = atoi(argumentPIN); + if (!parseStringToInt(argumentPIN, &PIN, 10)) { + perror("Invalid PIN"); + return EXIT_FAILURE; + } printf("Listening on PIN: %i\n", PIN); - } + } else { + printUsage(argv); + return EXIT_FAILURE; + } if (wiringPiSetup() == -1) { return EXIT_FAILURE; diff --git a/codesend b/codesend index 7ed2023129663c9a87cd1bfd1a502f5fb3cf8276..906d1a159673124a2c5d2b55cd0312c035560c9b 100755 GIT binary patch delta 6313 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 delta 5895 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 JqI^s??|+8#cnkml delta 5653 zcmbVQe{j^r6@Pm_!d-HgT#^HlT+CfAKRCybTp-rK#1at4AW48}TI2YmAVE<swh^f(a|uKn`=EV%NcQuj-f4|o z<_e3l(} zbzr?XJJB)^fsw^AFX&^S0CEKRr`7jh?VR*$`D9kukoGWIVAoU_#`XoVem>A?Sl4%Nl=Rl3%%HZ2u(KGM3Qz$25Ms#`kIbMvdQ~@!cA~S}yX`<$jb(oveft$0C9b zm&*q|W$q(01hvR#Ju}?bVeFmqBhPF%Pk*QMdoK~!%Q@bs#B%vh?^D5>P?;z(>Ka}= zMtuj5H=rT8++QRIvtJY)az)N;k(1n+bGO5BAS!cnZ+0E96_VR?j|kD5Torgqh%HHP zLDC@xk_Uq+AqJBNr{y`tz4C+NI&p{mzIa>lwdXGEW;u-MLf$N&F1ZD!ycsH#kx;40 zU1EQ`PL3t>w~ftBeqXj&1P@_9z7N0UYKOtUhAf*)ie$XpSMbhv7g{?M zmF?waQQ9|*=Xb^n`?Y=PZk}kBp0c~U7OtyBNt?LXVMq427hFtY@ zn|v580;}6Zfk8koQOB+{#(W4VBHp*ncc#aMXDDUn#?tN*NQNjDugK3iFp7V{S*5F!{}(2=iu?<>Qc#)E`o* zbqi6R0_Au-0h*O1WPf%2BXQrHBJ}rvW!V;g%V4uOISJm1#O88xnnvSXN5>ZC6C3e$ z60>PUY%nLMd74`Tu`mxdeZo4;lOBN|)^c(ZqC7SU@x_Fb)0{M(HidJ|^7tgSt_dyh zIZK~UBJ0v(VV+B*DmhkvV}2`#0wgElltAi~%VsT^uR0@i)`C*L@mML}!~ra$l`OgH zobM>C-zrCEg^f~8YbQz-cBoc0`C`b`ErV}6jMWecw~)QSD!J(E6w8D5lqmfgdkR?p z1d%jmmmAGm9|A@ztZeAg~E;UA@ycM*x<-+r9659EMqoB*pttZ-b%%0IiCPl zvP|@NRefvmx-)RIw%9x+Jr~Lis?1I|V6Kyf*^tv3X89Qnvs}3*Z(qg<1VbzN%{kns zVU~Mxb-4jY(F&f1tQQ9rhZ2EX9#=S%m#*+vuv;`a8+2Ziv;IJSTK^o_feihGCT~Ii zv^1EmP=(nY%&5?z$+?52a0M$_Bka&H%i|>%%9}LI@`Q#B9>G4XfE9){%<>}|X8Cyy zvz$Wd4p|=4Fw1K+%<_&jHq15ZOc$6_zEQ*6z-A3|1N$}1@<9!^^9%wvqFgzAS6SM? zYa!>m2w&s{8O79x0=}$R1;vyE<_n9$rU6<5Y`~}Cbc18iSBZlO%ZIdG#q}pNeU?|^ zCTS+aj$V<;ZDM)x@kyL-MK4vs)*mcS8}LtXP0k&bP8wwS3}0tCUCBWi;cYUh z5m1%tpn%SD2R7!Dk{di-t9qSE9@#c0Yy@#PJ7bp$JS8szo|x1sq*~xp8lDeKb~F(< zkJ)T>P+?b^y~HMivd@&)X!sh`4^9^}fO-YwH)t&i*pq6k0_q3m%PB7;KiOVjx!qv^ z5%v$jd_`9Be=tULiQDz3dvNyH`Vr`#g`CeOOFxgiV44tJR-5{UpDIysq*xXBX#p_5 z83r(wu#m0-K8z0dmjL72fmP!B$9)-iE3p2;+zG6Xha2IeJWyLkzZ0&_sOrrb}bfqShbF`$q~ zLHrWw!U$UJ250gw5GgU~@_MB;g7VpnwCe>fksGQg@*O+=ZUu2C;@4Z2dn1t6jlP^=IG&oLD*ODPWZ% z%%DA$ctBHtxjy%gBeZ!-zp5x%z33H({A}^V;)q<^8qVey4IiW< zLhfoU^YVjcHO$>D54MKA{G7>Rzn9~!VK+Z!7D{hhg`1x-n`M1lg_mDqytOvS8`{Ed zc2}R=gmUYN1^hS#nKtIFJjG? p;z@*mTeJ Date: Tue, 17 Oct 2017 23:41:47 -0700 Subject: [PATCH 14/19] Use pthread_mutex_timedlock to make sure the program does not hang forever when trying to acquire a lock --- RFSource/codesend | Bin 25932 -> 26120 bytes RFSource/codesend.cpp | 24 +++++++++++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/RFSource/codesend b/RFSource/codesend index 906d1a159673124a2c5d2b55cd0312c035560c9b..f176637cfdefa1706983474c5645bb86bd8ffd16 100755 GIT binary patch delta 8850 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 delta 7975 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 #include #include +#include #include "RCSwitch.h" #include "RFOutlet.h" @@ -95,7 +96,28 @@ int main(int argc, char *argv[]) { // printf("A previous codesend instance has already acquired a lock. Waiting!\n"); // } - pthread_mutex_lock(mutex.ptr); + // 2 second timeout for acquiring the lock + struct timespec abs_time; + clock_gettime(CLOCK_REALTIME , &abs_time); + abs_time.tv_sec += 2; + + if (pthread_mutex_timedlock(mutex.ptr, &abs_time) != 0) { + const char * const fd_path = "/proc/self/fd"; + const char *shm_path = NULL; + size_t needed = snprintf(NULL, 0, "%s/%d", fd_path, mutex.shm_fd) + 1; + char *buffer = (char *)malloc(needed); + if (snprintf(buffer, needed, "%s/%d", fd_path, mutex.shm_fd) >= 0) { + shm_path = realpath(buffer, NULL); + } + free(buffer); + + if (shm_path == NULL) { + shm_path = "/dev/shm"; + } + + fprintf(stderr, "Could not acquire an exclusive lock to activate the hardware, please try deleting the lock file at '%s' and try again\n", shm_path); + return EXIT_FAILURE; + } if (wiringPiSetup () == -1) { return EXIT_FAILURE; From f10b7b53466afb5ff0ee010937befb0f15b9d486 Mon Sep 17 00:00:00 2001 From: Marc Etcheverry Date: Fri, 20 Oct 2017 23:47:50 -0700 Subject: [PATCH 15/19] Better abort handling --- RFSource/codesend | Bin 26120 -> 26308 bytes RFSource/codesend.cpp | 27 ++++++++++++++++----------- codesend | Bin 25932 -> 26308 bytes 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/RFSource/codesend b/RFSource/codesend index f176637cfdefa1706983474c5645bb86bd8ffd16..89e7fdf3fb7eeb756d082c247c1f4cfab6272315 100755 GIT binary patch delta 7977 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 AzW@LL delta 7620 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 G+5Z8cAoF1W diff --git a/RFSource/codesend.cpp b/RFSource/codesend.cpp index 4fc63c6..35234b8 100755 --- a/RFSource/codesend.cpp +++ b/RFSource/codesend.cpp @@ -11,6 +11,7 @@ #define DEFAULT_PIN 0 #define DEFAULT_PULSE_LENGTH 189 +#define DEFAULT_HW_LOCK_TIMEOUT 2 shared_mutex_t mutex; @@ -18,11 +19,19 @@ void printUsage(char *argv[]) { printf("Usage: %s [-p (default: %i)] [-l (default: %i)].\n", argv[0], DEFAULT_PIN, DEFAULT_PULSE_LENGTH); } -void interruptHandler(int signal) { - // None of the pthread functions are async signal safe - printf("Please wait until proper shut down.\n"); +void *interruptThread(void *signal) { + printf("Shutting down...\n"); + // Give the locking mechanism some time and then exit + sleep(DEFAULT_HW_LOCK_TIMEOUT + 1); + exit(*(int *)signal); } +void interruptHandler(int signal) { + pthread_t thread; + if (pthread_create(&thread, NULL, interruptThread, &signal) != 0) { + exit(signal); + } +} int main(int argc, char *argv[]) { signal(SIGINT, interruptHandler); @@ -85,21 +94,17 @@ int main(int argc, char *argv[]) { return EXIT_FAILURE; } - // Acquire the shared mutex - // Set a permissive mode since codesend may be executed by www-data and other terminal users. Make the shared memory wide open + // Acquire the shared mutex and set a permissive mode since codesend may be executed by www-data and other terminal users mutex = shared_mutex_init("codesend_mutex", S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + if (mutex.ptr == NULL) { return EXIT_FAILURE; } - // if (!mutex.created) { - // printf("A previous codesend instance has already acquired a lock. Waiting!\n"); - // } - - // 2 second timeout for acquiring the lock + // Timeout for acquiring the lock, so we don't hang the process! struct timespec abs_time; clock_gettime(CLOCK_REALTIME , &abs_time); - abs_time.tv_sec += 2; + abs_time.tv_sec += DEFAULT_HW_LOCK_TIMEOUT; if (pthread_mutex_timedlock(mutex.ptr, &abs_time) != 0) { const char * const fd_path = "/proc/self/fd"; diff --git a/codesend b/codesend index 906d1a159673124a2c5d2b55cd0312c035560c9b..89e7fdf3fb7eeb756d082c247c1f4cfab6272315 100755 GIT binary patch delta 9534 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 delta 8310 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 From 4f5b7139271b61677dfb1c427f099e6ee619197f Mon Sep 17 00:00:00 2001 From: Marc Etcheverry Date: Fri, 20 Oct 2017 23:48:36 -0700 Subject: [PATCH 16/19] Update permissions --- .gitignore | 0 README.md | 0 RFSource/RCSwitch.cpp | 0 RFSource/RCSwitch.h | 0 script.js | 0 5 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 .gitignore mode change 100644 => 100755 README.md mode change 100644 => 100755 RFSource/RCSwitch.cpp mode change 100644 => 100755 RFSource/RCSwitch.h mode change 100644 => 100755 script.js diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 diff --git a/RFSource/RCSwitch.cpp b/RFSource/RCSwitch.cpp old mode 100644 new mode 100755 diff --git a/RFSource/RCSwitch.h b/RFSource/RCSwitch.h old mode 100644 new mode 100755 diff --git a/script.js b/script.js old mode 100644 new mode 100755 From 8b3d0e7cc160819a5834a3fabe8351b64dfc7d4e Mon Sep 17 00:00:00 2001 From: Marc Etcheverry Date: Tue, 16 Jan 2018 14:17:55 -0800 Subject: [PATCH 17/19] Add support for up to 10 outlets. Make sure 'all' is used instead of 6 to avoid conflicts. Add support for status reporting --- configuration.inc.php | 20 +++++++++++++++++ index.html | 50 ++++++++++++++++++++++++++++++++++++++++++- status.php | 15 +++++++++++++ toggle.php | 41 ++++++++++++++++++++++++++++++----- 4 files changed, 120 insertions(+), 6 deletions(-) mode change 100644 => 100755 index.html create mode 100755 status.php mode change 100644 => 100755 toggle.php diff --git a/configuration.inc.php b/configuration.inc.php index ee7385e..008ad5b 100644 --- a/configuration.inc.php +++ b/configuration.inc.php @@ -21,6 +21,26 @@ "on" => 357635, "off" => 357644 ), + "6" => array( + "on" => 349491, + "off" => 349500 + ), + "7" => array( + "on" => 349635, + "off" => 349644 + ), + "8" => array( + "on" => 349955, + "off" => 349964 + ), + "9" => array( + "on" => 351491, + "off" => 351500 + ), + "10" => array( + "on" => 357635, + "off" => 357644 + ) ); // Path to the codesend binary (current directory is the default) diff --git a/index.html b/index.html old mode 100644 new mode 100755 index 190fb92..a47e3fe --- a/index.html +++ b/index.html @@ -79,7 +79,7 @@ - +

@@ -88,6 +88,54 @@
+ + +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ + +
+
+ +
+
+ +
+
+ diff --git a/status.php b/status.php new file mode 100755 index 0000000..8cdfb11 --- /dev/null +++ b/status.php @@ -0,0 +1,15 @@ + false))); } -$outletLight = (!empty($_POST['outletId'])) ? $_POST['outletId'] : $_GET['outletId']; +$outletToToggle = (!empty($_POST['outletId'])) ? $_POST['outletId'] : $_GET['outletId']; $outletStatus = (!empty($_POST['outletStatus'])) ? $_POST['outletStatus'] : $_GET['outletStatus']; -if (empty($outletLight) || empty($outletStatus)) { +if (empty($outletToToggle) || empty($outletStatus)) { error_log('Missing POST paremeters', 0); die(json_encode(array('success' => false))); } -if ($outletLight == "6") { - // 6 is all 5 outlets combined +// Add check to see if outlet to toggle is in our codes or not + +if ($outletToToggle == "all") { + // all is every outlets combined if (function_exists('array_column')) { // PHP >= 5.5 $codesToToggle = array_column($codes, $outletStatus); @@ -31,7 +33,7 @@ } } else { // One - $codesToToggle = array($codes[$outletLight][$outletStatus]); + $codesToToggle = array($codes[$outletToToggle][$outletStatus]); } $returnCode = 0; @@ -44,4 +46,33 @@ } } +$status_contents = file_get_contents('status.json'); + +$statuses = NULL; + +if ($status_contents === FALSE || $outletToToggle == "all") { + $defaultStatus = 0; + if ($outletToToggle == "all") { + $defaultStatus = $outletStatus == "on" ? 1 : 0; + } + + $statuses = array(); + + foreach ($codes as $outletNumber=>$information) { + $statuses[$outletNumber] = $defaultStatus; + } +} else { + $statuses = json_decode($status_contents, true); +} + +if ($outletToToggle != "all") { + $statuses[$outletToToggle] = $outletStatus == "on" ? 1 : 0; +} + +$JSON = json_encode($statuses, JSON_PRETTY_PRINT); + +if (file_put_contents('status.json', $JSON) === FALSE) { + die(json_encode(array('success' => false, 'output' => "file_put_contents"))); +} + die(json_encode(array('success' => true))); From fdf408d0dedc5ef41d1e1a855c0940a15284c8e1 Mon Sep 17 00:00:00 2001 From: Marc Etcheverry Date: Tue, 16 Jan 2018 14:20:10 -0800 Subject: [PATCH 18/19] Move configuration to a sample file to avoid git conflicts --- .gitignore | 2 ++ configuration.inc.php => configuration.inc.php.sample | 0 2 files changed, 2 insertions(+) mode change 100755 => 100644 .gitignore rename configuration.inc.php => configuration.inc.php.sample (100%) diff --git a/.gitignore b/.gitignore old mode 100755 new mode 100644 index 97efaa5..9179a8a --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ *.DS_Store *.o +status.json +configuration.inc.php diff --git a/configuration.inc.php b/configuration.inc.php.sample similarity index 100% rename from configuration.inc.php rename to configuration.inc.php.sample From ec117ec319a6301e8c617edf3cfbaed157e0edaa Mon Sep 17 00:00:00 2001 From: Marc Etcheverry Date: Tue, 16 Jan 2018 14:31:43 -0800 Subject: [PATCH 19/19] Homebridge instructions --- README.md | 5 ++ homebridge-http.config.json.sample | 133 +++++++++++++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100644 homebridge-http.config.json.sample diff --git a/README.md b/README.md index 2aeeef9..a783c56 100755 --- a/README.md +++ b/README.md @@ -4,6 +4,11 @@ Have you ever wanted to wirelessly control power outlets from your phone using a **Blog Post:** [TimLeland.com/wireless-power-outlets](https://timleland.com/wireless-power-outlets/) +Homebridge +* A sample configuration file for the [Homebridge HTTP plugin](https://github.com/rudders/homebridge-http) is included at `homebridge-http.config.json.sample` +* You may want to set a longer polling interval following the instructions [here](https://github.com/rudders/homebridge-http/issues/76) +* Please note that the status tracking for Homebridge does not yet support receiving RF signals from the remote + Voice Control Outlets (Follow up Guides) * [Siri using HomeBridge](https://timleland.com/use-siri-to-control-wireless-power-outlets-homebridge/) * [Google Home](https://timleland.com/use-google-home-to-control-wireless-power-outlets/) diff --git a/homebridge-http.config.json.sample b/homebridge-http.config.json.sample new file mode 100644 index 0000000..0da3f6c --- /dev/null +++ b/homebridge-http.config.json.sample @@ -0,0 +1,133 @@ +{ + "bridge": { + "name": "HomeBridge", + "username": "CD:43:8A:C5:CD:42", + "port": 51826, + "pin": "124-45-678" + }, + + "description": "HomeBridge HTTP Status Control", + + "accessories": [ + { + "accessory": "Http", + "name": "Outlet 1", + "switchHandling": "realtime", + "http_method": "GET", + "on_url": "http://localhost/rfoutlet/toggle.php?outletId=1&outletStatus=on", + "off_url": "http://localhost/rfoutlet/toggle.php?outletId=1&outletStatus=off", + "status_url": "http://localhost/rfoutlet/status.php?outletId=1", + "service": "Light", + "brightnessHandling": "no", + "sendimmediately": "" + }, + { + "accessory": "Http", + "name": "Outlet 2", + "switchHandling": "realtime", + "http_method": "GET", + "on_url": "http://localhost/rfoutlet/toggle.php?outletId=2&outletStatus=on", + "off_url": "http://localhost/rfoutlet/toggle.php?outletId=2&outletStatus=off", + "status_url": "http://localhost/rfoutlet/status.php?outletId=2", + "service": "Light", + "brightnessHandling": "no", + "sendimmediately": "" + }, + { + "accessory": "Http", + "name": "Outlet 3", + "switchHandling": "realtime", + "http_method": "GET", + "on_url": "http://localhost/rfoutlet/toggle.php?outletId=3&outletStatus=on", + "off_url": "http://localhost/rfoutlet/toggle.php?outletId=3&outletStatus=off", + "status_url": "http://localhost/rfoutlet/status.php?outletId=3", + "service": "Light", + "brightnessHandling": "no", + "sendimmediately": "" + }, + { + "accessory": "Http", + "name": "Outlet 4", + "switchHandling": "realtime", + "http_method": "GET", + "on_url": "http://localhost/rfoutlet/toggle.php?outletId=4&outletStatus=on", + "off_url": "http://localhost/rfoutlet/toggle.php?outletId=4&outletStatus=off", + "status_url": "http://localhost/rfoutlet/status.php?outletId=4", + "service": "Light", + "brightnessHandling": "no", + "sendimmediately": "" + }, + { + "accessory": "Http", + "name": "Outlet 5", + "switchHandling": "realtime", + "http_method": "GET", + "on_url": "http://localhost/rfoutlet/toggle.php?outletId=5&outletStatus=on", + "off_url": "http://localhost/rfoutlet/toggle.php?outletId=5&outletStatus=off", + "status_url": "http://localhost/rfoutlet/status.php?outletId=5", + "service": "Light", + "brightnessHandling": "no", + "sendimmediately": "" + }, + { + "accessory": "Http", + "name": "Outlet 6", + "switchHandling": "realtime", + "http_method": "GET", + "on_url": "http://localhost/rfoutlet/toggle.php?outletId=6&outletStatus=on", + "off_url": "http://localhost/rfoutlet/toggle.php?outletId=6&outletStatus=off", + "status_url": "http://localhost/rfoutlet/status.php?outletId=6", + "service": "Light", + "brightnessHandling": "no", + "sendimmediately": "" + }, + { + "accessory": "Http", + "name": "Outlet 7", + "switchHandling": "realtime", + "http_method": "GET", + "on_url": "http://localhost/rfoutlet/toggle.php?outletId=7&outletStatus=on", + "off_url": "http://localhost/rfoutlet/toggle.php?outletId=7&outletStatus=off", + "status_url": "http://localhost/rfoutlet/status.php?outletId=7", + "service": "Light", + "brightnessHandling": "no", + "sendimmediately": "" + }, + { + "accessory": "Http", + "name": "Outlet 8", + "switchHandling": "realtime", + "http_method": "GET", + "on_url": "http://localhost/rfoutlet/toggle.php?outletId=8&outletStatus=on", + "off_url": "http://localhost/rfoutlet/toggle.php?outletId=8&outletStatus=off", + "status_url": "http://localhost/rfoutlet/status.php?outletId=8", + "service": "Light", + "brightnessHandling": "no", + "sendimmediately": "" + }, + { + "accessory": "Http", + "name": "Outlet 9", + "switchHandling": "realtime", + "http_method": "GET", + "on_url": "http://localhost/rfoutlet/toggle.php?outletId=9&outletStatus=on", + "off_url": "http://localhost/rfoutlet/toggle.php?outletId=9&outletStatus=off", + "status_url": "http://localhost/rfoutlet/status.php?outletId=9", + "service": "Light", + "brightnessHandling": "no", + "sendimmediately": "" + }, + { + "accessory": "Http", + "name": "Outlet 10", + "switchHandling": "realtime", + "http_method": "GET", + "on_url": "http://localhost/rfoutlet/toggle.php?outletId=10&outletStatus=on", + "off_url": "http://localhost/rfoutlet/toggle.php?outletId=10&outletStatus=off", + "status_url": "http://localhost/rfoutlet/status.php?outletId=10", + "service": "Light", + "brightnessHandling": "no", + "sendimmediately": "" + } + ] +}