commit 0687dc23833f5e09cc3273da2ed4acf7b27b5bf9 Author: Mentalflow <312902918@qq.com> Date: Wed Sep 2 00:00:50 2020 +0800 Initial project. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..4f34401 --- /dev/null +++ b/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2019 Kim Sung-Jun + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/README.md b/README.md new file mode 100644 index 0000000..347ee67 --- /dev/null +++ b/README.md @@ -0,0 +1,41 @@ +# homebridge-raspberrypi-switch +This is Raspberry Pi Remote plugin for [Homebridge](https://github.com/nfarina/homebridge). + + + +### Features +* Shutdown or reboot Raspberry Pi through homekit button. + + + +### Installation +1. Install required packages. + + ``` + cd project-dir | npm install -g + ``` + +2. Check the OS of Raspberry Pi. + +3. Add these values to `config.json`. + + ``` + "accessories": [ + { + "accessory": "pi_switch", + "name": "Raspberry Pi", + "os": "linux", + "serial": "123-456-789" + } + ] + ``` + +4. Restart Homebridge, and your Raspberry Pi will be added to Home app. + + +# Credits +[clauzewitz](https://github.com/clauzewitz/homebridge-raspberrypi-remote) for main body. +[bachandi](https://github.com/bachandi/homebridge-raspberrypi-info/tree/fixes)for get_Model() function. + +# License +MIT License diff --git a/example.config.json b/example.config.json new file mode 100644 index 0000000..80618db --- /dev/null +++ b/example.config.json @@ -0,0 +1,17 @@ +{ + "bridge": { + "name": "Homebridge", + "username": "CC:22:3D:E3:CE:30", + "port": 51826, + "pin": "123-45-568" + }, + + "accessories": [ + { + "accessory": "pi_switch", + "name": "Raspberry Pi", + "os": "linux", + "serial": "123-456-789" + } + ] +} diff --git a/index.js b/index.js new file mode 100644 index 0000000..a35364e --- /dev/null +++ b/index.js @@ -0,0 +1,146 @@ +'use strict'; + +var os = require("os"); +const exec = require('child_process').exec; +const inherits = require('util').inherits; +const version = require('./package.json').version; +let deviceInfo = {}; +let Service; +let Characteristic; + +module.exports = function (homebridge) { + Service = homebridge.hap.Service; + Characteristic = homebridge.hap.Characteristic; + + homebridge.registerAccessory('homebridge-raspberrypi-switch', 'pi_switch', pi_switch); +} + +function initCustomService() { + /** + * Service "pi_switch" Based on Service.Switch + */ + let raspberryPiUUID = '00000049-0000-1000-8000-0026BB765291'; + Service.pi_switch = function (displayName, subType) { + Service.call(this, displayName, raspberryPiUUID, subType); + + // Required Characteristics + this.addCharacteristic(Characteristic.On); + + // Optional Characteristics + this.addOptionalCharacteristic(Characteristic.Name); + } + + inherits(Service.pi_switch, Service); + Service.pi_switch.UUID = raspberryPiUUID; +} + +function getModel() { + + const { execSync } = require('child_process'); + // stderr is sent to stderr of parent process + // you can set options.stdio if you want it to go elsewhere + let stdout = execSync('cat /sys/firmware/devicetree/base/model'); + const data = stdout.toString(); + return data.substring(0, data.length - 1); +}; + +function pi_switch(log, config) { + this.log = log; + this.services = []; + this.name = config.name || 'Respberry Pi'; + this.os = config.os || 'linux'; + this.serial = config.serial || os.hostname(); + this.operatingState = true; + + initCustomService(); + + this.service = new Service.pi_switch(this.name, 'Shutdown'); + this.serviceInfo = new Service.AccessoryInformation(); + + this.service + .getCharacteristic(Characteristic.On) + .on('get', this.getPowerState.bind(this)) + .on('set', this.setPowerState.bind(this)); + + this.serviceInfo + .setCharacteristic(Characteristic.Manufacturer, 'Raspberry Pi Foundation') + .setCharacteristic(Characteristic.Model, getModel()) + .setCharacteristic(Characteristic.SerialNumber, this.serial) + .setCharacteristic(Characteristic.FirmwareRevision, version); + + this.services.push(this.service); + this.services.push(this.serviceInfo); + + this.rebootService = new Service.Switch(this.name + ' Reboot', 'Reboot'); + + this.rebootService + .getCharacteristic(Characteristic.On) + .on('get', this.getRebootState.bind(this)) + .on('set', this.setRebootState.bind(this)); + + this.services.push(this.rebootService); + +} + +pi_switch.prototype = { + + getPowerState: function (callback) { + callback(null, this.operatingState); + }, + + setPowerState: function (state, callback) { + if (!this.operatingState) { + return; + } + + const that = this; + + exec('sudo shutdown -h now', function (error, stdout, stderr) { + if (error) { + that.log(error); + } else { + that.operatingState = false; + + that.log.debug('operating state: %s', that.operatingState); + + callback(null, that.operatingState); + } + }); + }, + + getRebootState: function (callback) { + if (!this.operatingState) { + return; + } + + callback(null, !this.operatingState); + }, + + setRebootState: function (state, callback) { + if (!this.operatingState) { + return; + } + + const that = this; + + exec('sudo reboot', function (error, stdout, stderr) { + if (error) { + that.log(error); + } else { + that.operatingState = false; + + that.log.debug('operating state: %s', that.operatingState); + + callback(null, that.operatingState); + } + }); + }, + + identify: function (callback) { + callback(); + }, + + getServices: function () { + return this.services; + } +}; diff --git a/package.json b/package.json new file mode 100644 index 0000000..4dbea54 --- /dev/null +++ b/package.json @@ -0,0 +1,20 @@ +{ + "name": "homebridge-raspberrypi-switch", + "version": "1.0.0", + "description": "Raspberry Pi Remote Switch plugin for Homebridge.", + "license": "MIT", + "keywords": [ + "homebridge-plugin", + "raspberry pi", + "raspberrypi", + "switch" + ], + "repository": { + "type": "git", + "url": "https://github.com/Dracanrage/homebridge-raspberrypi-switch" + }, + "engines": { + "node": ">=0.12.0", + "homebridge": ">=0.4.0" + } +}