├── .gitignore ├── docs ├── 71FyoY6RWWL._SL1500_.jpg └── raspberry-pi-funksteckdosen_Steckplatine-678x1024.png ├── CHANGELOG.md ├── sample-config.json ├── package.json ├── README.md ├── sample-homebridge └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | *.log 4 | config.json 5 | homebridge 6 | -------------------------------------------------------------------------------- /docs/71FyoY6RWWL._SL1500_.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChristopherNeuwirth/homebridge-rc433-etekcity/HEAD/docs/71FyoY6RWWL._SL1500_.jpg -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 1.0.4 4 | - Implemented Queueing System by mxmerz 5 | 6 | 7 | ## 1.0.3 8 | - Minor Bugfixes 9 | 10 | ## 1.0.2 11 | - Basic functionality 12 | -------------------------------------------------------------------------------- /docs/raspberry-pi-funksteckdosen_Steckplatine-678x1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChristopherNeuwirth/homebridge-rc433-etekcity/HEAD/docs/raspberry-pi-funksteckdosen_Steckplatine-678x1024.png -------------------------------------------------------------------------------- /sample-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "bridge": { 3 | "name": "Homebridge", 4 | "username": "CC:22:3D:E3:CE:30", 5 | "port": 40500, 6 | "pin": "133-71-337" 7 | }, 8 | 9 | "description": "Your Chateau Homebridge", 10 | 11 | "accessories": [ 12 | { 13 | "accessory": "RC433EtekcitySwitch", 14 | "name": "Switch One", 15 | "id": "01", 16 | "pulse": "180", 17 | "on": "5566771", 18 | "off": "5577660" 19 | } 20 | ], 21 | 22 | "platforms": [] 23 | } 24 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "homebridge-rc433-etekcity", 3 | "version": "1.0.3", 4 | "description": "A Homebridge plugin for controlling rc 433mhz switches with custom pulse lenght via iOS devices. ", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git://github.com/ChristopherNeuwirth/homebridge-rc433-etekcity" 12 | }, 13 | "bugs": { 14 | "url": "https://github.com/ChristopherNeuwirth/homebridge-rc433-etekcity/issues" 15 | }, 16 | "devDependencies": {}, 17 | "dependencies": { 18 | "rpi-433": "^2.1.0", 19 | "wiring-pi": "^2.2.0" 20 | }, 21 | "engines": { 22 | "node": ">=6.9.2", 23 | "homebridge": ">=0.2.0" 24 | }, 25 | "keywords": [ 26 | "rcswitch", 27 | "raspberry", 28 | "433", 29 | "pi", 30 | "siri", 31 | "homebridge", 32 | "homebridge-plugin", 33 | "ios", 34 | "homekit" 35 | ], 36 | "author": "Christopher Neuwirth", 37 | "license": "ISC" 38 | } 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Homebridge RC433 Etekcity Plugin 2 | 3 | This Homebridge plugin enables you to control [433mhz Etekcity switchs](https://www.amazon.de/dp/B016I3TZ58/ref=wl_it_dp_o_pC_nS_ttl?_encoding=UTF8&colid=3NEM5I6QUP4AR&coliid=I166WF1IKFO0FK) by a Raspberry Pi. 4 | 5 | ![](https://raw.githubusercontent.com/ChristopherNeuwirth/homebridge-rc433-etekcity/master/docs/71FyoY6RWWL._SL1500_.jpg) 6 | 7 | The plugin is based on the idea of [FWeinb's rcswitch](https://github.com/FWeinb/homebridge-rcswitch) plugin. 8 | The Etekcity switches require a pulse length beside its controlling code given, therefore a basic rc433mhz 9 | implementation does not work. 10 | 11 | ## Setup 12 | 13 | 1) Wire a 433Mhz RF transmitter and receiver kit to your Raspberry Pi. You can find several instructions on the 14 | web (e.g. (German) [Click here](http://tutorials-raspberrypi.de/raspberry-pi-funksteckdosen-433-mhz-steuern/)). 15 | 16 | ![](https://raw.githubusercontent.com/ChristopherNeuwirth/homebridge-rc433-etekcity/master/docs/raspberry-pi-funksteckdosen_Steckplatine-678x1024.png) 17 | 18 | 2) Use wiring-pi and its rf sniffer to record the codes for your switches by launching the programm on your 19 | Raspberry Pi and controlling the switches by the remote control. Be aware of the fact that there are several 20 | implementations of the 433mhz protocol. The Etekcity switches require those which handle the pulse lenght. 21 | 22 | 3) Follow the intstructions to install [Homebridge](https://github.com/nfarina/homebridge/wiki/Running-HomeBridge-on-a-Raspberry-Pi) on your Raspberry Pi 23 | 24 | 4) Install this plugin 25 | 26 | ```bash 27 | npm i -g homebridge-rc433-etekcity 28 | ``` 29 | 30 | 5) Rename the sample-config.json to config.json and integrate your switches in the accessories array. The pins 31 | of the Raspberry Pi require root rights to control them. Therefore you have to save your config file not 32 | in your users directory. Put it under `/root/.homebridge/config.json`. 33 | If you are already running homekit with other apps integrate the accessories switches into your config.json 34 | and move your config file to the path above. 35 | 36 | 6) If you want to start homebrige as a service atomaticlly when the Raspberry is turned on copy over 37 | the file homebridge to `/etc/init.d/` on your Raspberry. 38 | -------------------------------------------------------------------------------- /sample-homebridge: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ### BEGIN INIT INFO 3 | # Provides: homebridge 4 | # Required-Start: $remote_fs $syslog 5 | # Required-Stop: $remote_fs $syslog 6 | # Default-Start: 2 3 4 5 7 | # Default-Stop: 0 1 6 8 | # Short-Description: Start daemon at boot time 9 | # Description: sudo homebridge 10 | ### END INIT INFO 11 | 12 | dir="/home/pi" 13 | cmd="sudo homebridge" 14 | user="pi" 15 | 16 | name=`basename $0` 17 | pid_file="/var/run/$name.pid" 18 | stdout_log="/var/log/$name.log" 19 | stderr_log="/var/log/$name.err" 20 | 21 | get_pid() { 22 | cat "$pid_file" 23 | } 24 | 25 | is_running() { 26 | [ -f "$pid_file" ] && ps `get_pid` > /dev/null 2>&1 27 | } 28 | 29 | case "$1" in 30 | start) 31 | if is_running; then 32 | echo "Already started" 33 | else 34 | echo "Starting $name" 35 | cd "$dir" 36 | if [ -z "$user" ]; then 37 | sudo $cmd >> "$stdout_log" 2>> "$stderr_log" & 38 | else 39 | sudo -u "$user" $cmd >> "$stdout_log" 2>> "$stderr_log" & 40 | fi 41 | echo $! > "$pid_file" 42 | if ! is_running; then 43 | echo "Unable to start, see $stdout_log and $stderr_log" 44 | exit 1 45 | fi 46 | fi 47 | ;; 48 | stop) 49 | if is_running; then 50 | echo -n "Stopping $name.." 51 | kill `get_pid` 52 | for i in {1..10} 53 | do 54 | if ! is_running; then 55 | break 56 | fi 57 | 58 | echo -n "." 59 | sleep 1 60 | done 61 | echo 62 | 63 | if is_running; then 64 | echo "Not stopped; may still be shutting down or shutdown may have failed" 65 | exit 1 66 | else 67 | echo "Stopped" 68 | if [ -f "$pid_file" ]; then 69 | rm "$pid_file" 70 | fi 71 | fi 72 | else 73 | echo "Not running" 74 | fi 75 | ;; 76 | restart) 77 | $0 stop 78 | if is_running; then 79 | echo "Unable to stop, will not attempt to start" 80 | exit 1 81 | fi 82 | $0 start 83 | ;; 84 | status) 85 | if is_running; then 86 | echo "Running" 87 | else 88 | echo "Stopped" 89 | exit 1 90 | fi 91 | ;; 92 | *) 93 | echo "Usage: $0 {start|stop|restart|status}" 94 | exit 1 95 | ;; 96 | esac 97 | 98 | exit 0 99 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const rpi433 = require('rpi-433'); 2 | const rfEmitter = rpi433.emitter({pin: 0, pulseLength: 179}); 3 | 4 | let Service; 5 | let Characteristic; 6 | 7 | // command queue 8 | let todoList = []; 9 | let timer = null; 10 | let timeout = 200; // timeout between sending rc commands (in ms) 11 | 12 | module.exports = (homebridge) => { 13 | Service = homebridge.hap.Service; 14 | Characteristic = homebridge.hap.Characteristic; 15 | homebridge.registerAccessory('homebridge-rc433-etekcity', 'RC433EtekcitySwitch', RC433EtekcitySwitch); 16 | }; 17 | 18 | class RC433EtekcitySwitch { 19 | constructor(log, config) { 20 | 21 | // config 22 | this.name = config['name']; 23 | this.id = config['id']; 24 | this.pulse = config['pulse']; 25 | this.signalOn = config['on']; 26 | this.signalOff = config['off']; 27 | 28 | // setup 29 | this.log = log; 30 | this.service = new Service.Switch(this.name); 31 | this.setupRcSwitchService(this.service); 32 | 33 | // information service 34 | this.informationService = new Service.AccessoryInformation(); 35 | this.informationService 36 | .setCharacteristic(Characteristic.Name, 'RC433EtekcitySwitch') 37 | .setCharacteristic(Characteristic.Manufacturer, 'CN') 38 | .setCharacteristic(Characteristic.Model, 'Etekcity ' + this.name) 39 | .setCharacteristic(Characteristic.SerialNumber, '1337-' + this.id); 40 | 41 | } 42 | 43 | getServices() { 44 | return [this.informationService, this.service]; 45 | } 46 | 47 | setupRcSwitchService(service) { 48 | let state = false; 49 | 50 | service 51 | .getCharacteristic(Characteristic.On) 52 | .on('set', (value, callback) => { 53 | state = value; 54 | let signal; 55 | if(state) { 56 | signal = this.signalOn; 57 | } else { 58 | signal = this.signalOff; 59 | } 60 | todoList.push({ 61 | 'signal': signal, 62 | 'callback': callback 63 | }); 64 | if (timer === null) { 65 | timer = setTimeout(this.toggleNext, timeout, this); 66 | } 67 | }); 68 | 69 | service 70 | .getCharacteristic(Characteristic.On) 71 | .on('get', (callback) => { 72 | callback(null, state); 73 | }); 74 | } 75 | 76 | toggleNext(switchObject) { 77 | // get next todo item 78 | let todoItem = todoList.shift(); 79 | let signal = todoItem['signal']; 80 | let callback = todoItem['callback']; 81 | // send signal 82 | rfEmitter.sendCode(signal, function(error, stdout) { 83 | if(error) { 84 | console.log('error ' + error); 85 | } else { 86 | console.log('success ' + stdout); 87 | }; 88 | }); 89 | // set timer for next todo 90 | if (todoList.length > 0) { 91 | timer = setTimeout(switchObject.toggleNext, timeout, switchObject); 92 | } else { 93 | timer = null; 94 | } 95 | // call callback 96 | callback(); 97 | } 98 | 99 | } 100 | --------------------------------------------------------------------------------