├── .gitignore ├── sample-config.json ├── package.json ├── LICENSE.md ├── README.md └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/* 2 | my-config.json 3 | test-config.json -------------------------------------------------------------------------------- /sample-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "bridge": { 3 | "name": "HomeBridge", 4 | "username": "CC:22:3D:E3:CE:40", 5 | "port": 51826, 6 | "pin": "031-45-154" 7 | }, 8 | "description": "HomeBridge OctoPrint Plugin", 9 | "accessories": [ 10 | { 11 | "accessory": "OctoPrint", 12 | "name": "OctoPrint", 13 | "api_key": "XXXXX" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "homebridge-octoprint", 3 | "version": "0.0.1", 4 | "description": "OctoPrint plugin for homebridge: https://github.com/nfarina/homebridge", 5 | "license": "MIT", 6 | "keywords": [ 7 | "homebridge-plugin" 8 | ], 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/JonathanH5/homebridge-octoprint" 12 | }, 13 | "bugs": { 14 | "url": "https://github.com/JonathanH5/homebridge-octoprint/issues" 15 | }, 16 | "dependencies": { 17 | "request": ">=2.83.0", 18 | "request-promise": ">=4.2.2" 19 | }, 20 | "engines": { 21 | "node": ">=0.12.0", 22 | "homebridge": ">=0.2.0" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Jonathan Hasenburg 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 | # homebridge-octoprint 2 | 3 | Plugin to support [OctoPrint](https://octopi.octoprint.org) 3D printer control via the [HomeBridge Platform](https://github.com/nfarina/homebridge). 4 | 5 | # Installation 6 | 7 | 1. Install homebridge using: npm install -g homebridge 8 | 2. Install homebridge-octoprint using: npm install -g homebridge-octoprint 9 | 3. Update your configuration file. See sample-config.json in this repository for a sample or below. 10 | 11 | ``` 12 | "accessories": [ 13 | { 14 | "accessory": "OctoPrint", 15 | "name": "OctoPrint", 16 | "api_key": "XXXXX" 17 | } 18 | ] 19 | ``` 20 | 21 | # What does this plugin do? 22 | 23 | This plugin adds the current print status of OctoPrint to HomeKit. The print status is shown as a lightbulb, with the brightness value equaling the current print progress (0-100%). If you deactivate the lightbulb, octoprint is instructed to abort the current print. Note, that print jobs cannot be started with this plugin (so activating the lightbulb does not do anything). 24 | 25 | # Notes for implementation 26 | 27 | ## Possible Characteristics and Services 28 | Description of characteristics (available methods and how to build listener) can be found [here]( https://github.com/KhaosT/HAP-NodeJS/blob/master/lib/Characteristic.js). Characteristics hava a setValue() and a getValue() method. 29 | 30 | Overview of all available characteristics and services can be found [here](https://github.com/KhaosT/HAP-NodeJS/blob/master/lib/gen/HomeKitTypes.js). 31 | 32 | When adding characteristics: 33 | * getCharacteristic: Searches for characteristic in service and returns it. If non existent but optional -> create one and return it 34 | * setCharacteristic: getCharacteristic + setValue() 35 | 36 | ## Start in Developer Mode 37 | 38 | To start the plugin in developer mode run `homebridge -D -P . -U ~/.homebridge-dev/` while beeing in the root directory. A sample config has to be saved at `~/.homebridge-dev/`. 39 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var Service, Characteristic; 2 | var ReqP = require("request-promise"); 3 | 4 | module.exports = function(homebridge){ 5 | Service = homebridge.hap.Service; 6 | Characteristic = homebridge.hap.Characteristic; 7 | // registration of each accessory 8 | homebridge.registerAccessory("homebridge-octoprint","OctoPrint",OctoPrint); 9 | } 10 | 11 | //************************************************************************************************** 12 | // General Functions 13 | //************************************************************************************************** 14 | 15 | 16 | 17 | //************************************************************************************************** 18 | // Bricklet Remote Switch 19 | //************************************************************************************************** 20 | 21 | function OctoPrint(log, config) { 22 | this.log = log; 23 | 24 | // parse config 25 | this.name = config["name"]; 26 | this.server = config["server"] || 'http://octopi.local'; 27 | this.apiKey = config["api_key"]; 28 | 29 | log.info("Initialized OctoPrint Accessory at " + this.server); 30 | } 31 | 32 | OctoPrint.prototype = { 33 | getServices: function() { 34 | 35 | var informationService = new Service.AccessoryInformation(); 36 | informationService 37 | .setCharacteristic(Characteristic.Manufacturer, "Guy Sheffer and the Community") 38 | .setCharacteristic(Characteristic.Model, "OctoPrint"); 39 | 40 | var controlService = new Service.Lightbulb(); 41 | 42 | controlService 43 | .getCharacteristic(Characteristic.On) 44 | .on('get', this.getPrintingState.bind(this)) 45 | .on('set', this.setPrintingState.bind(this)); 46 | 47 | controlService 48 | .getCharacteristic(Characteristic.Brightness) 49 | .on('get', this.getProgress.bind(this)) 50 | .on('set', this.setProgress.bind(this)); 51 | 52 | // set name 53 | controlService.setCharacteristic(Characteristic.Name, this.name); 54 | 55 | return [informationService, controlService]; 56 | }, 57 | 58 | // This function gets the current printing state (1 = printing, 0 = not printing) 59 | getPrintingState(callback) { 60 | this.log('Getting current printing state: GET ' + this.server + '/api/printer'); 61 | 62 | var options = { 63 | method: 'GET', 64 | uri: this.server + '/api/printer', 65 | headers: { 66 | "X-Api-Key": this.apiKey 67 | }, 68 | json: true 69 | }; 70 | 71 | ReqP(options).then(function(printState) { 72 | var state = printState.state.flags.printing; 73 | console.log("Printer is printing: " + state) 74 | if (state == false) { 75 | callback(null, 0); 76 | } else { 77 | callback(null, 1); 78 | } 79 | }) 80 | .catch(function(error) { 81 | callback(error); 82 | }); 83 | }, 84 | 85 | /* 86 | This function sets the current printing state. It is only allowed to shut down the printer 87 | */ 88 | setPrintingState(value, callback) { 89 | if (value == 1) { 90 | console.log("You cannot start a print with homekit."); 91 | callback(1); 92 | } else { 93 | console.log("Stopping print."); 94 | var options = { 95 | method: 'POST', 96 | uri: this.server + '/api/job', 97 | headers: { 98 | "X-Api-Key": this.apiKey 99 | }, 100 | body: { 101 | "command": "cancel" 102 | }, 103 | json: true 104 | }; 105 | ReqP(options).then(function(printState) { 106 | console.log("Print stopped successfully.") 107 | callback(null); 108 | }) 109 | .catch(function(error) { 110 | callback(error); 111 | }); 112 | } 113 | }, 114 | 115 | /* 116 | This function gets the current progress of the print job and stores it as a 117 | lightbulb's brightness value. 118 | */ 119 | getProgress(callback) { 120 | this.log('Getting current job data: GET ' + this.server + '/api/job'); 121 | 122 | var options = { 123 | method: 'GET', 124 | uri: this.server + '/api/job', 125 | headers: { 126 | "X-Api-Key": this.apiKey 127 | }, 128 | json: true 129 | }; 130 | 131 | ReqP(options).then(function(printState) { 132 | var completion = printState.progress.completion; 133 | if (completion == null) { 134 | console.log("Printer currently not printing.") 135 | callback(null, 0); 136 | } else { 137 | console.log("Current completion: " + JSON.stringify(completion)); 138 | completionInt = Math.round(parseFloat(completion)); 139 | callback(null, completionInt); 140 | } 141 | }) 142 | .catch(function(error) { 143 | callback(error); 144 | }); 145 | }, 146 | 147 | /* 148 | Not allowed. 149 | */ 150 | setProgress(value, callback) { 151 | console.log("Cannot set progress with homekit!"); 152 | callback(1); 153 | } 154 | } 155 | --------------------------------------------------------------------------------