homebridge-homeassistant-mbmccormick
Version:
Homebridge plugin for Home Assistant: https://home-assistant.io
277 lines (244 loc) • 8.96 kB
JavaScript
'use strict';
let Service;
let Characteristic;
let communicationError;
function HomeAssistantMediaPlayer(log, data, client, firmware) {
/* eslint-disable no-unused-vars */
const SUPPORT_PAUSE = 1;
const SUPPORT_SEEK = 2;
const SUPPORT_VOLUME_SET = 4;
const SUPPORT_VOLUME_MUTE = 8;
const SUPPORT_PREVIOUS_TRACK = 16;
const SUPPORT_NEXT_TRACK = 32;
const SUPPORT_TURN_ON = 128;
const SUPPORT_TURN_OFF = 256;
const SUPPORT_VOLUME_STEP = 1024;
const SUPPORT_STOP = 4096;
const SUPPORT_PLAY = 16384;
/* eslint-enable no-unused-vars */
// device info
this.domain = 'media_player';
this.data = data;
this.entity_id = data.entity_id;
this.uuid_base = data.entity_id;
this.firmware = firmware;
this.supportedFeatures = data.attributes.supported_features;
this.stateLogicCompareWithOn = true;
if (data.attributes && data.attributes.friendly_name) {
this.name = data.attributes.friendly_name;
} else {
this.name = data.entity_id.split('.').pop().replace(/_/g, ' ');
}
const supportPause = (this.supportedFeatures | SUPPORT_PAUSE) === this.supportedFeatures;
const supportStop = (this.supportedFeatures | SUPPORT_STOP) === this.supportedFeatures;
const supportOnOff = ((this.supportedFeatures | SUPPORT_TURN_ON) === this.supportedFeatures &&
(this.supportedFeatures | SUPPORT_TURN_OFF) === this.supportedFeatures);
this.supportMute = (this.supportedFeatures | SUPPORT_VOLUME_MUTE) === this.supportedFeatures;
this.supportVolume = (this.supportedFeatures | SUPPORT_VOLUME_SET) === this.supportedFeatures;
if (this.data && this.data.attributes && this.data.attributes.homebridge_media_player_switch === 'on_off' && supportOnOff) {
this.onState = 'on';
this.offState = 'off';
this.onService = 'turn_on';
this.offService = 'turn_off';
this.stateLogicCompareWithOn = false;
} else if (this.data && this.data.attributes && this.data.attributes.homebridge_media_player_switch === 'play_stop' && supportStop) {
this.onState = 'playing';
this.offState = 'idle';
this.onService = 'media_play';
this.offService = 'media_stop';
} else if (supportPause) {
this.onState = 'playing';
this.offState = 'paused';
this.onService = 'media_play';
this.offService = 'media_pause';
} else if (supportStop) {
this.onState = 'playing';
this.offState = 'idle';
this.onService = 'media_play';
this.offService = 'media_stop';
} else if (supportOnOff) {
this.onState = 'on';
this.offState = 'off';
this.onService = 'turn_on';
this.offService = 'turn_off';
}
if (data.attributes && data.attributes.homebridge_manufacturer) {
this.manufacturer = String(data.attributes.homebridge_manufacturer);
} else {
this.manufacturer = 'Home Assistant';
}
if (data.attributes && data.attributes.homebridge_model) {
this.model = String(data.attributes.homebridge_model);
} else {
this.model = 'Media Player';
}
if (data.attributes && data.attributes.homebridge_serial) {
this.serial = String(data.attributes.homebridge_serial);
} else {
this.serial = data.entity_id;
}
this.client = client;
this.log = log;
}
HomeAssistantMediaPlayer.prototype = {
onEvent(oldState, newState) {
if (newState.state) {
let powerState;
if (this.stateLogicCompareWithOn) {
powerState = newState.state === this.onState;
} else {
powerState = newState.state !== this.offState;
}
this.switchService.getCharacteristic(Characteristic.On)
.setValue(powerState, null, 'internal');
}
},
getPowerState(callback) {
this.log(`fetching power state for: ${this.name}`);
this.client.fetchState(this.entity_id, (data) => {
if (data) {
let powerState;
if (this.stateLogicCompareWithOn) {
powerState = data.state === this.onState;
} else {
powerState = data.state !== this.offState;
}
callback(null, powerState);
} else {
callback(communicationError);
}
});
},
setPowerState(powerOn, callback, context) {
if (context === 'internal') {
callback();
return;
}
const that = this;
const serviceData = {};
serviceData.entity_id = this.entity_id;
if (powerOn) {
this.log(`Setting power state on the '${this.name}' to on`);
this.client.callService(this.domain, this.onService, serviceData, (data) => {
if (data) {
that.log(`Successfully set power state on the '${that.name}' to on`);
callback();
} else {
callback(communicationError);
}
});
} else {
this.log(`Setting power state on the '${this.name}' to off`);
this.client.callService(this.domain, this.offService, serviceData, (data) => {
if (data) {
that.log(`Successfully set power state on the '${that.name}' to off`);
callback();
} else {
callback(communicationError);
}
});
}
},
getMuteState(callback) {
this.log(`fetching mute state for: ${this.name}`);
this.client.fetchState(this.entity_id, (data) => {
if (data) {
callback(null, data.attributes.is_volume_muted);
} else {
callback(communicationError);
}
});
},
setMuteState(muteOn, callback, context) {
if (context === 'internal') {
callback();
return;
}
const that = this;
const serviceData = {};
serviceData.entity_id = this.entity_id;
serviceData.is_volume_muted = (muteOn) ? 'true' : 'false';
this.log(`Setting mute state on the '${this.name}' to ${serviceData.is_volume_muted}`);
this.client.callService(this.domain, 'volume_mute', serviceData, (data) => {
if (data) {
that.log(`Successfully set mute state on the '${that.name}' to ${serviceData.is_volume_muted}`);
callback();
} else {
callback(communicationError);
}
});
},
getVolume(callback) {
this.log(`fetching volume for: ${this.name}`);
this.client.fetchState(this.entity_id, (data) => {
if (data) {
let volume;
if (!(data.attributes.volume_level)) {
volume = 0;
} else {
volume = (data.attributes.volume_level * 100);
}
callback(null, volume);
} else {
callback(communicationError);
}
});
},
setVolume(volume, callback, context) {
if (context === 'internal') {
callback();
return;
}
const that = this;
const serviceData = {};
serviceData.entity_id = this.entity_id;
serviceData.volume_level = volume / 100;
this.log(`Setting volume on the '${this.name}' to ${volume}%`);
this.client.callService(this.domain, 'volume_set', serviceData, (data) => {
if (data) {
that.log(`Successfully set volume on the '${that.name}' to ${serviceData.volume_level}`);
callback();
} else {
callback(communicationError);
}
});
},
getServices() {
this.switchService = new Service.Switch();
const informationService = new Service.AccessoryInformation();
informationService
.setCharacteristic(Characteristic.Manufacturer, this.manufacturer)
.setCharacteristic(Characteristic.Model, this.model)
.setCharacteristic(Characteristic.SerialNumber, this.serial)
.setCharacteristic(Characteristic.FirmwareRevision, this.firmware);
this.switchService
.getCharacteristic(Characteristic.On)
.on('get', this.getPowerState.bind(this))
.on('set', this.setPowerState.bind(this));
if (this.supportMute) {
this.speakerService = new Service.Speaker();
this.speakerService
.setCharacteristic(Characteristic.Name, this.name);
this.speakerService
.getCharacteristic(Characteristic.Mute)
.on('get', this.getMuteState.bind(this))
.on('set', this.setMuteState.bind(this));
if (this.supportVolume) {
this.speakerService
.getCharacteristic(Characteristic.Volume)
.on('get', this.getVolume.bind(this))
.on('set', this.setVolume.bind(this));
}
return [informationService, this.switchService, this.speakerService];
}
return [informationService, this.switchService];
},
};
function HomeAssistantMediaPlayerPlatform(oService, oCharacteristic, oCommunicationError) {
Service = oService;
Characteristic = oCharacteristic;
communicationError = oCommunicationError;
return HomeAssistantMediaPlayer;
}
module.exports = HomeAssistantMediaPlayerPlatform;
module.exports.HomeAssistantMediaPlayer = HomeAssistantMediaPlayer;