homebridge-aircast
Version:
homebridge-aircast provides simple HomeKit integration for aircast via homebridge
165 lines (138 loc) • 4.55 kB
JavaScript
var request = require('request')
var fs = require('fs')
var inherits = require('util').inherits
var path = require('path')
var Service, Characteristic, VolumeCharacteristic
module.exports = function (homebridge) {
Service = homebridge.hap.Service
Characteristic = homebridge.hap.Characteristic
makeVolumeCharacteristic()
homebridge.registerPlatform('homebridge-aircast', 'Aircast', AircastPlatform)
}
function AircastPlatform (log, config) {
this.log = log
this.url = config['url']
this.requestConfig = {
'json': true
}
this.log('Aircast Platform Plugin Version ' + this.getVersion())
};
AircastPlatform.prototype.accessories = function (callback) {
var self = this
request
.get(this.url + 'devices', this.requestConfig)
.on('response', function (response) {
response.on('data', function (chunk) {
self.data = JSON.parse(chunk) || []
callback(self.createAccessories())
})
})
.on('error', function (err) {
throw new Error(err)
})
}
AircastPlatform.prototype.createAccessories = function () {
var self = this
return this.data.map(function (value) {
return new AircastAccessory(value, self)
})
}
AircastPlatform.prototype.getVersion = function () {
var pjPath = path.join(__dirname, './package.json')
var pj = JSON.parse(fs.readFileSync(pjPath))
return pj.version
}
function AircastAccessory (data, platform) {
this.data = data
this.platform = platform
this.name = data.name.split('@').pop()
this.log = this.platform.log
this.service = new Service.Switch(this.name)
this.service
.getCharacteristic(Characteristic.On)
.on('get', this._getOn.bind(this))
.on('set', this._setOn.bind(this))
this.service
.addCharacteristic(VolumeCharacteristic)
.on('get', this._getVolume.bind(this))
.on('set', this._setVolume.bind(this))
}
AircastAccessory.prototype.getInformationService = function () {
var informationService = new Service.AccessoryInformation()
informationService
.setCharacteristic(Characteristic.Name, this.name)
.setCharacteristic(Characteristic.Manufacturer, 'Aircast')
.setCharacteristic(Characteristic.Model, this.platform.getVersion())
.setCharacteristic(Characteristic.SerialNumber, this.data.name)
return informationService
}
AircastAccessory.prototype.getServices = function () {
return [this.service, this.getInformationService()]
}
AircastAccessory.prototype._getDevice = function (callback) {
request
.get(this.platform.url + 'devices/' + this.data.name, this.platform.requestConfig)
.on('response', function (response) {
response.on('data', function (chunk) {
callback(JSON.parse(chunk) || {})
})
})
.on('error', function (err) {
throw new Error(err)
})
}
AircastAccessory.prototype._setDeviceCharacteristic = function (characteristic, value, callback) {
var requestConfig = Object.assign({
body: {}
}, this.platform.requestConfig)
requestConfig.body[characteristic] = value
request
.put(this.platform.url + 'devices/' + this.data.name + '/' + characteristic, requestConfig)
.on('response', function (response) {
response.on('data', function (chunk) {
callback(JSON.parse(chunk) || {})
})
})
.on('error', function (err) {
throw new Error(err)
})
}
AircastAccessory.prototype._getOn = function (callback) {
this._getDevice(function (device) {
callback(null, device.connected)
})
}
AircastAccessory.prototype._setOn = function (on, callback) {
this._setDeviceCharacteristic('connect', !!on, function (device) {
callback(null)
})
}
AircastAccessory.prototype._getVolume = function (callback) {
this._getDevice(function (device) {
callback(null, device.volume * 1)
})
}
AircastAccessory.prototype._setVolume = function (volume, callback) {
this._setDeviceCharacteristic('volume', volume, function (device) {
callback(null)
})
}
//
// Custom Characteristic for Volume
// Thanks to @CONNCTED
//
function makeVolumeCharacteristic () {
VolumeCharacteristic = function () {
Characteristic.call(this, 'Volume', '91288267-5678-49B2-8D22-F57BE995AA00')
this.setProps({
format: Characteristic.Formats.INT,
unit: Characteristic.Units.PERCENTAGE,
maxValue: 100,
minValue: 0,
minStep: 1,
perms: [Characteristic.Perms.READ, Characteristic.Perms.WRITE, Characteristic.Perms.NOTIFY]
})
this.value = this.getDefaultValue()
}
inherits(VolumeCharacteristic, Characteristic)
};