Update: WIP realtime refresh of state of available play services

realtime_play_button
Juraj Nyíri 3 years ago
parent 531d19f584
commit d154ecd30d

@ -19327,6 +19327,8 @@ const isScrolledIntoView = (elem) => {
class PlayController { class PlayController {
constructor(hass, plex, entity, runBefore, runAfter, libraryName) { constructor(hass, plex, entity, runBefore, runAfter, libraryName) {
this.readyPlayersForType = {};
this.entityStates = {};
this.plexPlayerEntity = ''; this.plexPlayerEntity = '';
this.runBefore = false; this.runBefore = false;
this.runAfter = false; this.runAfter = false;
@ -19398,7 +19400,7 @@ class PlayController {
await waitUntilState(this.hass, entityID, 'off'); await waitUntilState(this.hass, entityID, 'off');
} }
} }
const entity = this.getPlayService(data); const entity = this.getPlayService(data, true);
let processData = data; let processData = data;
let provider; let provider;
if (lodash.isEqual(data.type, 'epg')) { if (lodash.isEqual(data.type, 'epg')) {
@ -19679,7 +19681,35 @@ class PlayController {
command command
}); });
}; };
this.getPlayService = (data) => { this.refreshAvailableServicesPeriodically = async () => {
const sleep = async (ms) => {
return new Promise(resolve => setTimeout(resolve, ms));
};
while (true) {
// eslint-disable-next-line no-await-in-loop
await this.refreshStates();
const previousReadyPlayersForType = lodash.clone(this.readyPlayersForType);
lodash.forEach(this.readyPlayersForType, (value, key) => {
const mockData = {
type: key
};
this.getPlayService(mockData, true);
if (!lodash.isEqual(previousReadyPlayersForType, this.readyPlayersForType)) {
console.log('CHANGED');
}
else {
console.log('SAME');
}
console.log(JSON.stringify(this.readyPlayersForType));
});
// eslint-disable-next-line no-await-in-loop
await sleep(1000);
}
};
this.getPlayService = (data, forceRefresh = false) => {
if (!lodash.isNil(this.readyPlayersForType[data.type]) && forceRefresh === false) {
return this.readyPlayersForType[data.type];
}
let service = {}; let service = {};
lodash.forEach(this.entity, (value, key) => { lodash.forEach(this.entity, (value, key) => {
if (lodash.isEmpty(service)) { if (lodash.isEmpty(service)) {
@ -19708,7 +19738,8 @@ class PlayController {
} }
} }
}); });
return service; this.readyPlayersForType[data.type] = service;
return this.readyPlayersForType[data.type];
}; };
this.init = async () => { this.init = async () => {
if (!lodash.isNil(this.entity.plexPlayer)) { if (!lodash.isNil(this.entity.plexPlayer)) {
@ -19747,6 +19778,23 @@ class PlayController {
await this.entity.plexPlayer.plex.getClients(); await this.entity.plexPlayer.plex.getClients();
} }
} }
await this.refreshStates();
};
this.refreshStates = async () => {
for (const [, value] of Object.entries(this.entity)) {
const entityVal = value;
if (lodash.isArray(entityVal)) {
for (const entity of entityVal) {
// eslint-disable-next-line no-await-in-loop
this.entityStates[entity] = await getState(this.hass, entity);
}
}
else {
// eslint-disable-next-line no-await-in-loop
this.entityStates[entityVal] = await getState(this.hass, entityVal);
}
}
return this.entityStates;
}; };
this.getPlexPlayerMachineIdentifier = (entity) => { this.getPlexPlayerMachineIdentifier = (entity) => {
let machineIdentifier = ''; let machineIdentifier = '';
@ -19785,27 +19833,27 @@ class PlayController {
}; };
this.isKodiSupported = (entityName) => { this.isKodiSupported = (entityName) => {
if (entityName) { if (entityName) {
const hasKodiMediaSearchInstalled = this.hass.states['sensor.kodi_media_sensor_search'] && const hasKodiMediaSearchInstalled = this.entityStates['sensor.kodi_media_sensor_search'] &&
this.hass.states['sensor.kodi_media_sensor_search'].state !== 'unavailable'; this.entityStates['sensor.kodi_media_sensor_search'].state !== 'unavailable';
return ((this.hass.states[entityName] && return ((this.entityStates[entityName] &&
this.hass.states[entityName].state !== 'off' && this.entityStates[entityName].state !== 'off' &&
this.hass.states[entityName].state !== 'unavailable' && this.entityStates[entityName].state !== 'unavailable' &&
hasKodiMediaSearchInstalled) || hasKodiMediaSearchInstalled) ||
(!lodash.isEqual(this.runBefore, false) && hasKodiMediaSearchInstalled)); (!lodash.isEqual(this.runBefore, false) && hasKodiMediaSearchInstalled));
} }
return false; return false;
}; };
this.isCastSupported = (entityName) => { this.isCastSupported = (entityName) => {
return ((this.hass.states[entityName] && return ((this.entityStates[entityName] &&
!lodash.isNil(this.hass.states[entityName].attributes) && !lodash.isNil(this.entityStates[entityName].attributes) &&
this.hass.states[entityName].state !== 'unavailable') || this.entityStates[entityName].state !== 'unavailable') ||
!lodash.isEqual(this.runBefore, false)); !lodash.isEqual(this.runBefore, false));
}; };
this.isAndroidTVSupported = (entityName) => { this.isAndroidTVSupported = (entityName) => {
return ((this.hass.states[entityName] && return ((this.entityStates[entityName] &&
!lodash.isEqual(this.hass.states[entityName].state, 'off') && !lodash.isEqual(this.entityStates[entityName].state, 'off') &&
this.hass.states[entityName].attributes && this.entityStates[entityName].attributes &&
this.hass.states[entityName].attributes.adb_response !== undefined) || this.entityStates[entityName].attributes.adb_response !== undefined) ||
!lodash.isEqual(this.runBefore, false)); !lodash.isEqual(this.runBefore, false));
}; };
this.hass = hass; this.hass = hass;
@ -19818,6 +19866,7 @@ class PlayController {
if (!lodash.isEmpty(runAfter) && this.hass.states[runAfter]) { if (!lodash.isEmpty(runAfter) && this.hass.states[runAfter]) {
this.runAfter = runAfter.split('.'); this.runAfter = runAfter.split('.');
} }
this.refreshAvailableServicesPeriodically();
} }
} }

@ -1,3 +1,4 @@
/* eslint-disable no-restricted-syntax */
/* eslint-disable consistent-return */ /* eslint-disable consistent-return */
/* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-env browser */ /* eslint-env browser */
@ -9,6 +10,10 @@ import { supported } from '../const';
import { waitUntilState, getState } from './utils'; import { waitUntilState, getState } from './utils';
class PlayController { class PlayController {
readyPlayersForType: Record<string, Record<string, any>> = {};
entityStates: Record<string, any> = {};
entity: Record<string, any>; entity: Record<string, any>;
plexPlayerEntity = ''; plexPlayerEntity = '';
@ -43,6 +48,8 @@ class PlayController {
if (!_.isEmpty(runAfter) && this.hass.states[runAfter]) { if (!_.isEmpty(runAfter) && this.hass.states[runAfter]) {
this.runAfter = runAfter.split('.'); this.runAfter = runAfter.split('.');
} }
this.refreshAvailableServicesPeriodically();
} }
private getKodiSearchResults = async (): Promise<Record<string, any>> => { private getKodiSearchResults = async (): Promise<Record<string, any>> => {
@ -116,7 +123,7 @@ class PlayController {
await waitUntilState(this.hass, entityID, 'off'); await waitUntilState(this.hass, entityID, 'off');
} }
} }
const entity = this.getPlayService(data); const entity = this.getPlayService(data, true);
let processData = data; let processData = data;
let provider; let provider;
@ -422,7 +429,36 @@ class PlayController {
}); });
}; };
private getPlayService = (data: Record<string, any>): Record<string, string> => { private refreshAvailableServicesPeriodically = async () => {
const sleep = async (ms: number): Promise<void> => {
return new Promise(resolve => setTimeout(resolve, ms));
};
while (true) {
// eslint-disable-next-line no-await-in-loop
await this.refreshStates();
const previousReadyPlayersForType = _.clone(this.readyPlayersForType);
_.forEach(this.readyPlayersForType, (value, key) => {
const mockData = {
type: key
};
this.getPlayService(mockData, true);
if (!_.isEqual(previousReadyPlayersForType, this.readyPlayersForType)) {
console.log('CHANGED');
} else {
console.log('SAME');
}
console.log(JSON.stringify(this.readyPlayersForType));
});
// eslint-disable-next-line no-await-in-loop
await sleep(1000);
}
};
private getPlayService = (data: Record<string, any>, forceRefresh = false): Record<string, string> => {
if (!_.isNil(this.readyPlayersForType[data.type]) && forceRefresh === false) {
return this.readyPlayersForType[data.type];
}
let service: Record<string, string> = {}; let service: Record<string, string> = {};
_.forEach(this.entity, (value, key) => { _.forEach(this.entity, (value, key) => {
if (_.isEmpty(service)) { if (_.isEmpty(service)) {
@ -454,7 +490,8 @@ class PlayController {
} }
} }
}); });
return service; this.readyPlayersForType[data.type] = service;
return this.readyPlayersForType[data.type];
}; };
init = async (): Promise<void> => { init = async (): Promise<void> => {
@ -505,6 +542,23 @@ class PlayController {
await this.entity.plexPlayer.plex.getClients(); await this.entity.plexPlayer.plex.getClients();
} }
} }
await this.refreshStates();
};
private refreshStates = async (): Promise<Record<string, any>> => {
for (const [, value] of Object.entries(this.entity)) {
const entityVal = value;
if (_.isArray(entityVal)) {
for (const entity of entityVal) {
// eslint-disable-next-line no-await-in-loop
this.entityStates[entity] = await getState(this.hass, entity);
}
} else {
// eslint-disable-next-line no-await-in-loop
this.entityStates[entityVal] = await getState(this.hass, entityVal);
}
}
return this.entityStates;
}; };
private getPlexPlayerMachineIdentifier = (entity: string | Record<string, any>): string => { private getPlexPlayerMachineIdentifier = (entity: string | Record<string, any>): string => {
@ -552,12 +606,12 @@ class PlayController {
private isKodiSupported = (entityName: string): boolean => { private isKodiSupported = (entityName: string): boolean => {
if (entityName) { if (entityName) {
const hasKodiMediaSearchInstalled = const hasKodiMediaSearchInstalled =
this.hass.states['sensor.kodi_media_sensor_search'] && this.entityStates['sensor.kodi_media_sensor_search'] &&
this.hass.states['sensor.kodi_media_sensor_search'].state !== 'unavailable'; this.entityStates['sensor.kodi_media_sensor_search'].state !== 'unavailable';
return ( return (
(this.hass.states[entityName] && (this.entityStates[entityName] &&
this.hass.states[entityName].state !== 'off' && this.entityStates[entityName].state !== 'off' &&
this.hass.states[entityName].state !== 'unavailable' && this.entityStates[entityName].state !== 'unavailable' &&
hasKodiMediaSearchInstalled) || hasKodiMediaSearchInstalled) ||
(!_.isEqual(this.runBefore, false) && hasKodiMediaSearchInstalled) (!_.isEqual(this.runBefore, false) && hasKodiMediaSearchInstalled)
); );
@ -567,19 +621,19 @@ class PlayController {
private isCastSupported = (entityName: string): boolean => { private isCastSupported = (entityName: string): boolean => {
return ( return (
(this.hass.states[entityName] && (this.entityStates[entityName] &&
!_.isNil(this.hass.states[entityName].attributes) && !_.isNil(this.entityStates[entityName].attributes) &&
this.hass.states[entityName].state !== 'unavailable') || this.entityStates[entityName].state !== 'unavailable') ||
!_.isEqual(this.runBefore, false) !_.isEqual(this.runBefore, false)
); );
}; };
private isAndroidTVSupported = (entityName: string): boolean => { private isAndroidTVSupported = (entityName: string): boolean => {
return ( return (
(this.hass.states[entityName] && (this.entityStates[entityName] &&
!_.isEqual(this.hass.states[entityName].state, 'off') && !_.isEqual(this.entityStates[entityName].state, 'off') &&
this.hass.states[entityName].attributes && this.entityStates[entityName].attributes &&
this.hass.states[entityName].attributes.adb_response !== undefined) || this.entityStates[entityName].attributes.adb_response !== undefined) ||
!_.isEqual(this.runBefore, false) !_.isEqual(this.runBefore, false)
); );
}; };

Loading…
Cancel
Save