├── .jshintrc ├── .travis.yml ├── config-sample.json ├── README.md ├── package.json └── index.js /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node": true, 3 | "esversion": 6 4 | } 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "6.1.0" 4 | before_script: 5 | - npm install 6 | script: 7 | - npm test 8 | notifications: 9 | email: false 10 | -------------------------------------------------------------------------------- /config-sample.json: -------------------------------------------------------------------------------- 1 | { 2 | "bridge": { 3 | "name": "Homebridge", 4 | "username": "CC:22:3D:E3:CE:30", 5 | "port": 51826, 6 | "pin": "031-45-154" 7 | }, 8 | 9 | "description": "This is an example configuration file. You can use this as a template for creating your own configuration file.", 10 | 11 | "platforms": [{ 12 | "platform": "Orvibo" 13 | }], 14 | 15 | "accessories": [] 16 | } 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/macnow/homebridge-platform-orvibo.svg?branch=master)](TravisBuild) 2 | 3 | # homebridge-platform-orvibo 4 | 5 | Orvibo Smart Socket plugin for [Homebridge](https://github.com/nfarina/homebridge). 6 | 7 | # Installation 8 | 9 | 1. Install Homebridge using: `npm install -g homebridge` 10 | 2. Install this plugin using: `npm install -g homebridge-platform-orvibo` 11 | 3. Update your configuration file. See the sample below. 12 | 13 | # Updating 14 | 15 | - `npm update -g homebridge-platform-orvibo` 16 | 17 | # Configuration 18 | 19 | ## Sample Configuration 20 | 21 | ```json 22 | "platforms": [{ 23 | "platform": "Orvibo" 24 | }], 25 | ``` 26 | 27 | 28 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "homebridge-platform-orvibo", 3 | "version": "1.0.2", 4 | "description": "Orvibo Smart Socket plugin for Homebridge", 5 | "author": "Maciej Nowakowski", 6 | "license": "MIT", 7 | "repository": { 8 | "type": "git", 9 | "url": "git://github.com/macnow/homebridge-platform-orvibo.git" 10 | }, 11 | "bugs": { 12 | "url": "https://github.com/macnow/homebridge-platform-orvibo/issues", 13 | "email": "macnow@gmail.com" 14 | }, 15 | "keywords": [ 16 | "homebridge-plugin", 17 | "homebridge", 18 | "orvibo", 19 | "s20", 20 | "home", 21 | "smartplug" 22 | ], 23 | "scripts": { 24 | "test": "jshint index.js" 25 | }, 26 | "engines": { 27 | "node": ">=4.4.0", 28 | "homebridge": ">=0.3.0" 29 | }, 30 | "dependencies": { 31 | "node-orvibo-2": "^1.1.5" 32 | }, 33 | "devDependencies": { 34 | "semistandard": "^9.0.0", 35 | "jshint": "^2.9.4" 36 | }, 37 | "scripts": { 38 | "debug": "DEBUG=* homebridge --debug --plugin-path .", 39 | "test": "./node_modules/.bin/semistandard", 40 | "preversion": "npm test", 41 | "postversion": "git push && git push --tags" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Orvibo = require('node-orvibo-2'); 4 | var Accessory, Service, Characteristic, UUIDGen; 5 | 6 | module.exports = function (homebridge) { 7 | Accessory = homebridge.platformAccessory; 8 | Service = homebridge.hap.Service; 9 | Characteristic = homebridge.hap.Characteristic; 10 | UUIDGen = homebridge.hap.uuid; 11 | 12 | homebridge.registerPlatform('homebridge-platform-orvibo', 'Orvibo', OrviboPlatform, true); 13 | }; 14 | 15 | class OrviboPlatform { 16 | constructor (log, config, api) { 17 | 18 | let self = this; 19 | 20 | self.log = log; 21 | self.config = config || {}; 22 | self.api = api; 23 | self.accessories = new Map(); 24 | 25 | self.orvibo = new Orvibo(); 26 | self.time1 = []; 27 | self.time2 = []; 28 | self.time3 = []; 29 | self.time4 = []; 30 | 31 | self.orvibo.on("deviceadded", function(device) { 32 | self.log("New Orvibo found: %s [%s]", device.type, device.macAddress); 33 | self.orvibo.discover(); 34 | 35 | self.time2[device.macAddress] = setInterval(function() { 36 | self.orvibo.subscribe(device); 37 | }, 1000); 38 | 39 | }); 40 | 41 | self.orvibo.on("subscribed", function(device) { 42 | self.log("Subscription to %s successful!", device.macAddress); 43 | clearInterval(self.time2[device.macAddress]); 44 | 45 | self.time3[device.macAddress] = setInterval(function() { 46 | self.orvibo.query({ device: device }); 47 | }, 1000); 48 | }); 49 | 50 | self.orvibo.on("queried", function(device) { 51 | self.log("A device has been queried. Name (if set): %s", device.name); 52 | clearInterval(self.time3[device.macAddress]); 53 | 54 | var accessory = self.accessories.get(device.macAddress); 55 | if (accessory === undefined) { 56 | self.addAccessory(device); 57 | } else { 58 | self.log("Orvibo Online: %s [%s]", accessory.displayName, device.macAddress); 59 | var OrviboAcc = new OrviboAccessory(self.log, accessory, self.orvibo); 60 | self.accessories.set(device.macAddress, OrviboAcc); 61 | OrviboAcc.configure(device); 62 | } 63 | }); 64 | self.orvibo.on("externalstatechanged", function(device) { 65 | self.log("State of %s set to %s", device.name, device.state); 66 | var OrviboAcc = self.accessories.get(device.macAddress); 67 | const outletService = OrviboAcc.accessory.getService(Service.Outlet); 68 | if (outletService.getCharacteristic(Characteristic.On).value != device.state) { 69 | outletService.getCharacteristic(Characteristic.On).setValue(device.state); 70 | } 71 | }); 72 | self.api.on('didFinishLaunching', this.didFinishLaunching.bind(this)); 73 | } 74 | 75 | configureAccessory (accessory) { 76 | this.accessories.set(accessory.context.deviceId, accessory); 77 | } 78 | 79 | didFinishLaunching () { 80 | var orvibo = this.orvibo; 81 | var time1 = this.time1; 82 | orvibo.listen(function() { 83 | time1 = setInterval(function() { 84 | orvibo.discover(); 85 | }, 5000); 86 | }); 87 | } 88 | 89 | addAccessory (device) { 90 | const name = device.name; 91 | this.log('Adding: %s', name); 92 | 93 | const platformAccessory = new Accessory(name, UUIDGen.generate(device.macAddress), 7 /* Accessory.Categories.OUTLET */); 94 | platformAccessory.addService(Service.Outlet, name); 95 | 96 | platformAccessory.context.deviceId = device.macAddress; 97 | //platformAccessory.context.device = device; 98 | 99 | const accessory = new OrviboAccessory(this.log, platformAccessory, this.orvibo); 100 | 101 | accessory.configure(); 102 | this.accessories.set(device.macAddress, accessory); 103 | this.api.registerPlatformAccessories('homebridge-platform-orvibo', 'Orvibo', [platformAccessory]); 104 | } 105 | 106 | removeAccessory (accessory) { 107 | this.log('Removing: %s', accessory.accessory.displayName); 108 | 109 | this.accessories.delete(accessory.accessory.macAddress); 110 | this.api.unregisterPlatformAccessories('homebridge-platform-orvibo', 'Orvibo', [accessory.accessory]); 111 | } 112 | 113 | } 114 | 115 | class OrviboAccessory { 116 | constructor (log, accessory, client) { 117 | this.log = log; 118 | 119 | this.accessory = accessory; 120 | this.client = client; 121 | this.macAddress = accessory.context.deviceId; 122 | this.device = client.getDevice(accessory.context.deviceId); 123 | 124 | } 125 | 126 | identify (callback) { 127 | // TODO 128 | callback(); 129 | } 130 | 131 | configure () { 132 | this.log('Configuring: %s', this.device.name); 133 | 134 | const pa = this.accessory; 135 | 136 | this.refresh(); 137 | 138 | const outletService = pa.getService(Service.Outlet); 139 | outletService.getCharacteristic(Characteristic.On) 140 | .on('get', (callback) => { 141 | this.refresh(); 142 | if (this.device.state === true) { 143 | callback(null, true); 144 | } else { 145 | callback(null, false); 146 | } 147 | }) 148 | .on('set', (value, callback) => { 149 | var state = value == 1; 150 | this.client.setState({device: this.device, state: state}); 151 | callback(); 152 | }); 153 | } 154 | 155 | refresh () { 156 | this.accessory.displayName = this.device.name; 157 | 158 | const outletService = this.accessory.getService(Service.Outlet); 159 | outletService.setCharacteristic(Characteristic.Name, this.device.name); 160 | if (outletService.getCharacteristic(Characteristic.On).value != this.device.state) { 161 | outletService.getCharacteristic(Characteristic.On).setValue(this.device.state); 162 | } 163 | 164 | const infoService = this.accessory.getService(Service.AccessoryInformation); 165 | infoService 166 | .setCharacteristic(Characteristic.Name, this.device.name) 167 | .setCharacteristic(Characteristic.Manufacturer, 'Orvibo') 168 | .setCharacteristic(Characteristic.Model, this.device.type) 169 | .setCharacteristic(Characteristic.SerialNumber, this.device.macAddress); 170 | 171 | this.accessory.context.lastRefreshed = new Date(); 172 | return this; 173 | } 174 | } 175 | --------------------------------------------------------------------------------