Add: Ability to use list for androidtv and plexPlayer entities

pull/16/head
Juraj Nyíri 3 years ago
parent e14dcfd082
commit 8f42c4fe49

@ -18805,16 +18805,16 @@ class PlayController {
return foundResult; return foundResult;
}; };
this.play = async (data, instantPlay = false) => { this.play = async (data, instantPlay = false) => {
const playService = this.getPlayService(data); const entity = this.getPlayService(data);
switch (playService) { switch (entity.key) {
case 'kodi': case 'kodi':
await this.playViaKodi(data, data.type); await this.playViaKodi(data, data.type);
break; break;
case 'androidtv': case 'androidtv':
await this.playViaAndroidTV(data.key.split('/')[3], instantPlay); await this.playViaAndroidTV(entity.value, data.key.split('/')[3], instantPlay);
break; break;
case 'plexPlayer': case 'plexPlayer':
await this.playViaPlexPlayer(data.key.split('/')[3]); await this.playViaPlexPlayer(entity.value, data.key.split('/')[3]);
break; break;
default: default:
throw Error(`No service available to play ${data.title}!`); throw Error(`No service available to play ${data.title}!`);
@ -18838,8 +18838,8 @@ class PlayController {
playQueueSelectedMetadataItemID: plexResponse.data.MediaContainer.playQueueSelectedMetadataItemID playQueueSelectedMetadataItemID: plexResponse.data.MediaContainer.playQueueSelectedMetadataItemID
}; };
}; };
this.playViaPlexPlayer = async (movieID) => { this.playViaPlexPlayer = async (entityName, movieID) => {
const machineID = !lodash.isEmpty(this.plexPlayerEntity) ? this.plexPlayerEntity : this.entity.plexPlayer; const machineID = this.getPlexPlayerMachineIdentifier(entityName);
const { playQueueID, playQueueSelectedMetadataItemID } = await this.plexPlayerCreateQueue(movieID); const { playQueueID, playQueueSelectedMetadataItemID } = await this.plexPlayerCreateQueue(movieID);
const url = `${this.plex.protocol}://${this.plex.ip}:${this.plex.port}/player/playback/playMedia?address=${this.plex.ip}&commandID=1&containerKey=/playQueues/${playQueueID}?window=100%26own=1&key=/library/metadata/${playQueueSelectedMetadataItemID}&machineIdentifier=${await this.plex.getServerID()}&offset=0&port=${this.plex.port}&token=${this.plex.token}&type=video&protocol=${this.plex.protocol}`; const url = `${this.plex.protocol}://${this.plex.ip}:${this.plex.port}/player/playback/playMedia?address=${this.plex.ip}&commandID=1&containerKey=/playQueues/${playQueueID}?window=100%26own=1&key=/library/metadata/${playQueueSelectedMetadataItemID}&machineIdentifier=${await this.plex.getServerID()}&offset=0&port=${this.plex.port}&token=${this.plex.token}&type=video&protocol=${this.plex.protocol}`;
try { try {
@ -18905,7 +18905,8 @@ class PlayController {
throw Error(`Plex type ${type} is not supported in Kodi.`); throw Error(`Plex type ${type} is not supported in Kodi.`);
} }
}; };
this.playViaAndroidTV = async (mediaID, instantPlay = false) => { this.playViaAndroidTV = async (entityName, mediaID, instantPlay = false) => {
console.log(entityName);
const serverID = await this.plex.getServerID(); const serverID = await this.plex.getServerID();
let command = `am start`; let command = `am start`;
if (instantPlay) { if (instantPlay) {
@ -18914,73 +18915,90 @@ class PlayController {
command += ` -a android.intent.action.VIEW 'plex://server://${serverID}/com.plexapp.plugins.library/library/metadata/${mediaID}'`; command += ` -a android.intent.action.VIEW 'plex://server://${serverID}/com.plexapp.plugins.library/library/metadata/${mediaID}'`;
this.hass.callService('androidtv', 'adb_command', { this.hass.callService('androidtv', 'adb_command', {
// eslint-disable-next-line @typescript-eslint/camelcase // eslint-disable-next-line @typescript-eslint/camelcase
entity_id: this.entity.androidtv, entity_id: entityName,
command: 'HOME' command: 'HOME'
}); });
this.hass.callService('androidtv', 'adb_command', { this.hass.callService('androidtv', 'adb_command', {
// eslint-disable-next-line @typescript-eslint/camelcase // eslint-disable-next-line @typescript-eslint/camelcase
entity_id: this.entity.androidtv, entity_id: entityName,
command command
}); });
}; };
this.getPlayService = (data) => { this.getPlayService = (data) => {
let service = ''; let service = {};
lodash.forEach(this.entity, (value, key) => { lodash.forEach(this.entity, (value, key) => {
if (lodash.isEmpty(service)) {
const entityVal = value;
if (lodash.isArray(entityVal)) {
lodash.forEach(entityVal, entity => {
if (lodash.includes(this.supported[key], data.type)) { if (lodash.includes(this.supported[key], data.type)) {
if ((key === 'kodi' && this.isKodiSupported()) || if ((key === 'kodi' && this.isKodiSupported(entity)) ||
(key === 'androidtv' && this.isAndroidTVSupported()) || (key === 'androidtv' && this.isAndroidTVSupported(entity)) ||
(key === 'plexPlayer' && this.isPlexPlayerSupported())) { (key === 'plexPlayer' && this.isPlexPlayerSupported(entity))) {
service = key; service = { key, value: entity };
return false; return false;
} }
} }
}); });
}
else if (lodash.includes(this.supported[key], data.type)) {
if ((key === 'kodi' && this.isKodiSupported(entityVal)) ||
(key === 'androidtv' && this.isAndroidTVSupported(entityVal)) ||
(key === 'plexPlayer' && this.isPlexPlayerSupported(entityVal))) {
service = { key, value: entityVal };
return false;
}
}
}
});
console.log('service');
console.log(service);
return service; return service;
}; };
this.isPlexPlayerSupported = () => { this.isPlexPlayerSupported = (entityName) => {
let found = false; let found = false;
lodash.forEach(this.plex.clients, plexClient => { if (this.getPlexPlayerMachineIdentifier(entityName)) {
if (lodash.isEqual(plexClient.machineIdentifier, this.entity.plexPlayer)) {
found = true; found = true;
return false;
} }
}); return found;
// Try to look into any other fields to identify machine ID };
if (!found) { this.getPlexPlayerMachineIdentifier = (entityName) => {
let machineIdentifier = '';
lodash.forEach(this.plex.clients, plexClient => { lodash.forEach(this.plex.clients, plexClient => {
if (lodash.isEqual(plexClient.product, this.entity.plexPlayer) || if (lodash.isEqual(plexClient.machineIdentifier, entityName) ||
lodash.isEqual(plexClient.name, this.entity.plexPlayer) || lodash.isEqual(plexClient.product, entityName) ||
lodash.isEqual(plexClient.host, this.entity.plexPlayer) || lodash.isEqual(plexClient.name, entityName) ||
lodash.isEqual(plexClient.address, this.entity.plexPlayer)) { lodash.isEqual(plexClient.host, entityName) ||
this.plexPlayerEntity = plexClient.machineIdentifier; lodash.isEqual(plexClient.address, entityName)) {
found = true; machineIdentifier = plexClient.machineIdentifier;
return false; return false;
} }
}); });
} return machineIdentifier;
return found;
}; };
this.isPlaySupported = (data) => { this.isPlaySupported = (data) => {
return !lodash.isEmpty(this.getPlayService(data)); return !lodash.isEmpty(this.getPlayService(data));
}; };
this.isKodiSupported = () => { this.isKodiSupported = (entityName) => {
if (this.entity.kodi) { if (entityName) {
return (this.hass.states[this.entity.kodi] && return (this.hass.states[entityName] &&
this.hass.states['sensor.kodi_media_sensor_search'] && this.hass.states['sensor.kodi_media_sensor_search'] &&
this.hass.states['sensor.kodi_media_sensor_search'].state !== 'unavailable' && this.hass.states['sensor.kodi_media_sensor_search'].state !== 'unavailable' &&
this.hass.states[this.entity.kodi].state !== 'off' && this.hass.states[entityName].state !== 'off' &&
this.hass.states[this.entity.kodi].state !== 'unavailable'); this.hass.states[entityName].state !== 'unavailable');
} }
return false; return false;
}; };
this.isAndroidTVSupported = () => { this.isAndroidTVSupported = (entityName) => {
return (this.hass.states[this.entity.androidtv] && return (this.hass.states[entityName] &&
this.hass.states[this.entity.androidtv].attributes && !lodash.isEqual(this.hass.states[entityName].state, 'off') &&
this.hass.states[this.entity.androidtv].attributes.adb_response !== undefined); this.hass.states[entityName].attributes &&
this.hass.states[entityName].attributes.adb_response !== undefined);
}; };
this.hass = hass; this.hass = hass;
this.plex = plex; this.plex = plex;
this.entity = entity; this.entity = entity;
console.log(entity);
} }
} }

@ -21,6 +21,7 @@ class PlayController {
this.hass = hass; this.hass = hass;
this.plex = plex; this.plex = plex;
this.entity = entity; this.entity = entity;
console.log(entity);
} }
private getState = async (entityID: string): Promise<Record<string, any>> => { private getState = async (entityID: string): Promise<Record<string, any>> => {
@ -83,16 +84,16 @@ class PlayController {
}; };
play = async (data: Record<string, any>, instantPlay = false): Promise<void> => { play = async (data: Record<string, any>, instantPlay = false): Promise<void> => {
const playService = this.getPlayService(data); const entity = this.getPlayService(data);
switch (playService) { switch (entity.key) {
case 'kodi': case 'kodi':
await this.playViaKodi(data, data.type); await this.playViaKodi(data, data.type);
break; break;
case 'androidtv': case 'androidtv':
await this.playViaAndroidTV(data.key.split('/')[3], instantPlay); await this.playViaAndroidTV(entity.value, data.key.split('/')[3], instantPlay);
break; break;
case 'plexPlayer': case 'plexPlayer':
await this.playViaPlexPlayer(data.key.split('/')[3]); await this.playViaPlexPlayer(entity.value, data.key.split('/')[3]);
break; break;
default: default:
throw Error(`No service available to play ${data.title}!`); throw Error(`No service available to play ${data.title}!`);
@ -121,8 +122,8 @@ class PlayController {
}; };
}; };
private playViaPlexPlayer = async (movieID: number): Promise<void> => { private playViaPlexPlayer = async (entityName: string, movieID: number): Promise<void> => {
const machineID = !_.isEmpty(this.plexPlayerEntity) ? this.plexPlayerEntity : this.entity.plexPlayer; const machineID = this.getPlexPlayerMachineIdentifier(entityName);
const { playQueueID, playQueueSelectedMetadataItemID } = await this.plexPlayerCreateQueue(movieID); const { playQueueID, playQueueSelectedMetadataItemID } = await this.plexPlayerCreateQueue(movieID);
const url = `${this.plex.protocol}://${this.plex.ip}:${this.plex.port}/player/playback/playMedia?address=${ const url = `${this.plex.protocol}://${this.plex.ip}:${this.plex.port}/player/playback/playMedia?address=${
@ -194,7 +195,8 @@ class PlayController {
} }
}; };
private playViaAndroidTV = async (mediaID: number, instantPlay = false): Promise<void> => { private playViaAndroidTV = async (entityName: string, mediaID: number, instantPlay = false): Promise<void> => {
console.log(entityName);
const serverID = await this.plex.getServerID(); const serverID = await this.plex.getServerID();
let command = `am start`; let command = `am start`;
@ -206,81 +208,99 @@ class PlayController {
this.hass.callService('androidtv', 'adb_command', { this.hass.callService('androidtv', 'adb_command', {
// eslint-disable-next-line @typescript-eslint/camelcase // eslint-disable-next-line @typescript-eslint/camelcase
entity_id: this.entity.androidtv, entity_id: entityName,
command: 'HOME' command: 'HOME'
}); });
this.hass.callService('androidtv', 'adb_command', { this.hass.callService('androidtv', 'adb_command', {
// eslint-disable-next-line @typescript-eslint/camelcase // eslint-disable-next-line @typescript-eslint/camelcase
entity_id: this.entity.androidtv, entity_id: entityName,
command command
}); });
}; };
private getPlayService = (data: Record<string, any>): string => { private getPlayService = (data: Record<string, any>): Record<string, string> => {
let service = ''; let service: Record<string, string> = {};
_.forEach(this.entity, (value, key) => { _.forEach(this.entity, (value, key) => {
if (_.isEmpty(service)) {
const entityVal = value;
if (_.isArray(entityVal)) {
_.forEach(entityVal, entity => {
if (_.includes(this.supported[key], data.type)) { if (_.includes(this.supported[key], data.type)) {
if ( if (
(key === 'kodi' && this.isKodiSupported()) || (key === 'kodi' && this.isKodiSupported(entity)) ||
(key === 'androidtv' && this.isAndroidTVSupported()) || (key === 'androidtv' && this.isAndroidTVSupported(entity)) ||
(key === 'plexPlayer' && this.isPlexPlayerSupported()) (key === 'plexPlayer' && this.isPlexPlayerSupported(entity))
) { ) {
service = key; service = { key, value: entity };
return false; return false;
} }
} }
}); });
} else if (_.includes(this.supported[key], data.type)) {
if (
(key === 'kodi' && this.isKodiSupported(entityVal)) ||
(key === 'androidtv' && this.isAndroidTVSupported(entityVal)) ||
(key === 'plexPlayer' && this.isPlexPlayerSupported(entityVal))
) {
service = { key, value: entityVal };
return false;
}
}
}
});
console.log('service');
console.log(service);
return service; return service;
}; };
isPlexPlayerSupported = (): boolean => { isPlexPlayerSupported = (entityName: string): boolean => {
let found = false; let found = false;
_.forEach(this.plex.clients, plexClient => { if (this.getPlexPlayerMachineIdentifier(entityName)) {
if (_.isEqual(plexClient.machineIdentifier, this.entity.plexPlayer)) {
found = true; found = true;
return false;
} }
}); return found;
// Try to look into any other fields to identify machine ID };
if (!found) {
private getPlexPlayerMachineIdentifier = (entityName: string): string => {
let machineIdentifier = '';
_.forEach(this.plex.clients, plexClient => { _.forEach(this.plex.clients, plexClient => {
if ( if (
_.isEqual(plexClient.product, this.entity.plexPlayer) || _.isEqual(plexClient.machineIdentifier, entityName) ||
_.isEqual(plexClient.name, this.entity.plexPlayer) || _.isEqual(plexClient.product, entityName) ||
_.isEqual(plexClient.host, this.entity.plexPlayer) || _.isEqual(plexClient.name, entityName) ||
_.isEqual(plexClient.address, this.entity.plexPlayer) _.isEqual(plexClient.host, entityName) ||
_.isEqual(plexClient.address, entityName)
) { ) {
this.plexPlayerEntity = plexClient.machineIdentifier; machineIdentifier = plexClient.machineIdentifier;
found = true;
return false; return false;
} }
}); });
} return machineIdentifier;
return found;
}; };
isPlaySupported = (data: Record<string, any>): boolean => { isPlaySupported = (data: Record<string, any>): boolean => {
return !_.isEmpty(this.getPlayService(data)); return !_.isEmpty(this.getPlayService(data));
}; };
private isKodiSupported = (): boolean => { private isKodiSupported = (entityName: string): boolean => {
if (this.entity.kodi) { if (entityName) {
return ( return (
this.hass.states[this.entity.kodi] && this.hass.states[entityName] &&
this.hass.states['sensor.kodi_media_sensor_search'] && this.hass.states['sensor.kodi_media_sensor_search'] &&
this.hass.states['sensor.kodi_media_sensor_search'].state !== 'unavailable' && this.hass.states['sensor.kodi_media_sensor_search'].state !== 'unavailable' &&
this.hass.states[this.entity.kodi].state !== 'off' && this.hass.states[entityName].state !== 'off' &&
this.hass.states[this.entity.kodi].state !== 'unavailable' this.hass.states[entityName].state !== 'unavailable'
); );
} }
return false; return false;
}; };
private isAndroidTVSupported = (): boolean => { private isAndroidTVSupported = (entityName: string): boolean => {
return ( return (
this.hass.states[this.entity.androidtv] && this.hass.states[entityName] &&
this.hass.states[this.entity.androidtv].attributes && !_.isEqual(this.hass.states[entityName].state, 'off') &&
this.hass.states[this.entity.androidtv].attributes.adb_response !== undefined this.hass.states[entityName].attributes &&
this.hass.states[entityName].attributes.adb_response !== undefined
); );
}; };
} }

Loading…
Cancel
Save