├── LICENSE ├── README.md ├── example_esp8266 └── example_esp8266.ino └── LivoloTx ├── LivoloTx.h └── LivoloTx.cpp /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Bitlinker 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LivoloTx 2 | Livolo radio protocol library for Arduino 3 | 4 | This is improved version of http://go.mysku.ru/?r=https%3A%2F%2Fdb.tt%2FtgBSk6oF&key=ms 5 | - Code is optimiezed 6 | - Eliminated redundant digitalWrite() calls 7 | 8 | # Original library description: 9 | 10 | Features: 11 | 12 | - emulates buttons 1 to 0 and ALL OFF of Livolo remote controller 13 | 14 | Usage: 15 | 16 | Basically you need two things to get it to work: 17 | 18 | 1) Create LivoloTx instance 19 | 2) Use sendButton() function to "push" the buttons 20 | 21 | sendButton function uses to arguments: remote ID and keycode. Typically, remote IDs are 16 bit unsigned values, but 22 | not all of them are valid (maybe there are some IDs reserved only for system use or there is something I don't know). 23 | 24 | Tested remote IDs: 25 | 26 | - read from real remote IDs: 6400; 19303 27 | - "virtual" remote IDs: 10550; 8500; 7400 28 | 29 | You can try and find new IDs as well: put your switch into learning mode and start sendButton with remote ID you wish to use. If 30 | it is a valid ID, switch will accept it. 31 | 32 | Keycodes read from real remote: 33 | 34 | #1: 0, #2: 96, #3: 120, #4: 24, #5: 80, #6: 48, #7: 108, #8: 12, #9: 72; #10: 40, #OFF: 106 35 | 36 | Keycodes are 7 bit values (actually I use 8 bit values, just skip most significant (leftmost) bit), but other keycodes 37 | could be reserved for system use (dimmer, for example). 38 | 39 | For an example sketch see example_esp8266.ino. 40 | -------------------------------------------------------------------------------- /example_esp8266/example_esp8266.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | static const char* WIFI_SSID = "!MY_WIFI_SSID!"; 8 | static const char* WIFI_PASSWORD = "!MY_WIFI_SSID!"; 9 | 10 | static const char* PASSCODE = "!SECRET!"; 11 | 12 | static const uint16_t LIVOLO_REMOTE_ID = 6400; 13 | 14 | static const int TX_PIN = D1; 15 | 16 | ESP8266WebServer server(8080); 17 | 18 | int nextCmd = 0; 19 | int nextBtn = 0; 20 | 21 | LivoloTx gLivolo(TX_PIN); 22 | 23 | void onLights() { 24 | const String& strButton = server.arg("command"); 25 | const String& strPassword = server.arg("secret"); 26 | if (strPassword.equals(PASSCODE)) 27 | { 28 | nextBtn = strButton.toInt(); 29 | nextCmd = 1; 30 | server.send(200, "text/plain", "lights on"); 31 | } 32 | else 33 | { 34 | server.send(403, "text/plain", "access denied"); 35 | } 36 | } 37 | 38 | void onIndex() { 39 | server.send(200, "text/html", "

This is the light switch!

"); 40 | } 41 | 42 | void connectWiFi() 43 | { 44 | WiFi.begin(WIFI_SSID, WIFI_PASSWORD); 45 | Serial.print("Connecting"); 46 | while (WiFi.status() != WL_CONNECTED) 47 | { 48 | delay(500); 49 | Serial.print("."); 50 | } 51 | Serial.println(); 52 | 53 | Serial.print("Connected, IP address: "); 54 | Serial.println(WiFi.localIP()); 55 | } 56 | 57 | void setup() 58 | { 59 | Serial.begin(115200); 60 | Serial.println(); 61 | 62 | pinMode(TX_PIN, OUTPUT); 63 | digitalWrite(TX_PIN, LOW); 64 | 65 | server.on("/lights", HTTP_ANY, onLights); 66 | server.on("/", onIndex); 67 | server.begin(); 68 | } 69 | 70 | void loop() { 71 | if (WiFi.status() != WL_CONNECTED) 72 | { 73 | connectWiFi(); 74 | } 75 | 76 | server.handleClient(); 77 | 78 | if (nextCmd) 79 | { 80 | gLivolo.sendButton(LIVOLO_REMOTE_ID, nextBtn); 81 | nextCmd = 0; 82 | nextBtn = 0; 83 | Serial.println("lights on!"); 84 | } 85 | } 86 | 87 | -------------------------------------------------------------------------------- /LivoloTx/LivoloTx.h: -------------------------------------------------------------------------------- 1 | /* 2 | LivoloTx - Arduino library implementing Livolo switches radio protocol 3 | 4 | Copyright (c) 2016 Bitlinker 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | #ifndef LivoloTx_h 26 | #define LivoloTx_h 27 | 28 | #include 29 | 30 | class LivoloTx 31 | { 32 | public: 33 | static const uint8_t KEY_MAX = 10; 34 | static constexpr uint8_t KEYS[KEY_MAX] = { 35 | 0, 36 | 96, 37 | 120, 38 | 24, 39 | 80, 40 | 48, 41 | 108, 42 | 12, 43 | 72, 44 | 40, 45 | }; 46 | static const uint8_t KEY_OFF = 106; 47 | 48 | public: 49 | explicit LivoloTx(int txPin); 50 | void sendButton(uint16_t remoteId, uint8_t keyId); 51 | 52 | private: 53 | void sendCommand(uint32_t command, uint8_t numBits); 54 | inline void sendOne(); 55 | inline void sendZero(); 56 | inline void sendPreamble(); 57 | inline void tx(bool value); 58 | 59 | private: 60 | bool mIsHigh; 61 | int mTxPin; 62 | }; 63 | 64 | #endif // LivoloTx_h 65 | -------------------------------------------------------------------------------- /LivoloTx/LivoloTx.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | LivoloTx - Arduino library implementing Livolo switches radio protocol 3 | 4 | Copyright (c) 2016 Bitlinker 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | 26 | #include "LivoloTx.h" 27 | #include 28 | #include 29 | 30 | #define LIVOLO_PREAMBLE_DURATION 525 31 | #define LIVOLO_ZERO_DURATION 120 32 | #define LIVOLO_ONE_DURATION 315 33 | #define LIVOLO_NUM_REPEATS 150 34 | 35 | LivoloTx::LivoloTx(int txPin) 36 | : mIsHigh(false) 37 | , mTxPin(txPin) 38 | { 39 | } 40 | 41 | void LivoloTx::sendButton(uint16_t remoteId, uint8_t keyId) 42 | { 43 | // 7 bit Key Id and 16 bit Remote Id 44 | uint32_t command = ((uint32_t)keyId & 0x7F) | (remoteId << 7); 45 | sendCommand(command, 23); 46 | } 47 | 48 | 49 | void LivoloTx::sendCommand(uint32_t command, uint8_t numBits) 50 | { 51 | for (uint8_t repeat = 0; repeat < LIVOLO_NUM_REPEATS; ++repeat) 52 | { 53 | uint32_t mask = (1 << (numBits - 1)); 54 | sendPreamble(); 55 | for (uint8_t i = numBits; i > 0; --i) 56 | { 57 | if ((command & mask) > 0) 58 | { 59 | sendOne(); 60 | } 61 | else 62 | { 63 | sendZero(); 64 | } 65 | mask >>= 1; 66 | } 67 | } 68 | tx(false); 69 | } 70 | 71 | void LivoloTx::sendOne() 72 | { 73 | delayMicroseconds(LIVOLO_ONE_DURATION); 74 | mIsHigh = !mIsHigh; 75 | tx(mIsHigh); 76 | } 77 | 78 | void LivoloTx::sendZero() 79 | { 80 | delayMicroseconds(LIVOLO_ZERO_DURATION); 81 | tx(!mIsHigh); 82 | delayMicroseconds(LIVOLO_ZERO_DURATION); 83 | tx(mIsHigh); 84 | } 85 | 86 | void LivoloTx::sendPreamble() 87 | { 88 | tx(true); 89 | delayMicroseconds(LIVOLO_PREAMBLE_DURATION); 90 | tx(false); 91 | mIsHigh = false; 92 | } 93 | 94 | void LivoloTx::tx(bool value) 95 | { 96 | digitalWrite(mTxPin, value ? HIGH : LOW); 97 | } 98 | --------------------------------------------------------------------------------