diff --git a/CHANGELOG.md b/CHANGELOG.md index cbef216..59fcdaa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.7.5] - 2021-09-05 +## Changes +- update config schema +- extend fiter possibility +- code cleanup + ## [1.7.3] - 2021-09-03 ## Changes diff --git a/README.md b/README.md index 49acec4..26a394f 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,7 @@ Install and use [Homebridge Config UI X](https://github.com/oznu/homebridge-conf | `getInputsFromDevice`| If `true` then enable possibility get apps direct from device, only available if `webApiControl` is enabled | | `filterGames`| If `true` Games will be hidden and not displayed in the inputs list, only available if `webApiControl` is enabled | | `filterApps`| If `true` Apps will be hidden and not displayed in the inputs list, only available if `webApiControl` is enabled | +| `filterSystemApps`| If `true` System Apps (Accessory, TV) will be hidden and not displayed in the inputs list, only available if `webApiControl` is enabled | | `filterDlc`| If `true` Dlc will be hidden and not displayed in the inputs list, only available if `webApiControl` is enabled | | `rebootControl`| If `true` then enable possibility reboot console, only available if `webApiControl` is enabled | | `inputs` | Configure apps/inputs which will be published and appear in HomeKit app in the device tile as inputs list, `Television`, `Dashboard`, `Accessory`, `Settings` inputs are created by default. | @@ -128,6 +129,10 @@ Install and use [Homebridge Config UI X](https://github.com/oznu/homebridge-conf "volumeControl": 0, "switchInfoMenu": false, "getInputsFromDevice": false, + "filterGames": false, + "filterApps": false, + "filterSystemApps": false, + "filterDlc": false, "rebootControl": false, "inputs": [ { diff --git a/config.schema.json b/config.schema.json index 238e4cb..4ff83af 100644 --- a/config.schema.json +++ b/config.schema.json @@ -125,6 +125,16 @@ "required": false, "description": "This toggle behaviour for *I* button in RC app and *PowerModeSelection* in settings." }, + "rebootControl": { + "title": "Enable reboot control", + "type": "boolean", + "default": false, + "required": false, + "description": "This enable possibility reboot console if web api is enabled.", + "condition": { + "functionBody": "return model.devices[arrayIndices].webApiControl === true;" + } + }, "getInputsFromDevice": { "title": "Load inputs from device", "type": "boolean", @@ -152,27 +162,27 @@ "required": false, "description": "If enabled, Apps will not be displayed on the list of inputs.", "condition": { - "functionBody": "return model.devices[arrayIndices].getInputsFromDevice === tru && model.devices[arrayIndices].webApiControl === true" + "functionBody": "return model.devices[arrayIndices].getInputsFromDevice === true && model.devices[arrayIndices].webApiControl === true" } }, - "filterDlc": { - "title": "Hide DLC", + "filterSystemApps": { + "title": "Hide System Apps", "type": "boolean", "default": false, "required": false, - "description": "If enabled, DLC will not be displayed on the list of inputs.", + "description": "If enabled, System Apps (Accessory, TV) will not be displayed on the list of inputs.", "condition": { "functionBody": "return model.devices[arrayIndices].getInputsFromDevice === true && model.devices[arrayIndices].webApiControl === true" } }, - "rebootControl": { - "title": "Enable reboot control", + "filterDlc": { + "title": "Hide DLC", "type": "boolean", "default": false, "required": false, - "description": "This enable possibility reboot console if web api is enabled.", + "description": "If enabled, DLC will not be displayed on the list of inputs.", "condition": { - "functionBody": "return model.devices[arrayIndices].webApiControl === true;" + "functionBody": "return model.devices[arrayIndices].getInputsFromDevice === true && model.devices[arrayIndices].webApiControl === true" } }, "inputs": { @@ -351,21 +361,28 @@ "title": "Inputs", "expandable": true, "expanded": false, - "items": [{ - "key": "devices[].inputs", - "type": "array", - "orderable": false, - "buttonText": "Add input", - "items": [ - "devices[].inputs[].name", - "devices[].inputs[].reference", - "devices[].inputs[].oneStoreProductId", - "devices[].inputs[].type" - ] - }], - "condition": { - "functionBody": "return model.devices && model.devices[arrayIndices].getInputsFromDevice === false || model.devices[arrayIndices].webApiControl === false;" - } + "items": [ + "devices[].getInputsFromDevice", + "devices[].filterGames", + "devices[].filterApps", + "devices[].filterSystemApps", + "devices[].filterDlc", + { + "key": "devices[].inputs", + "type": "array", + "orderable": false, + "buttonText": "Add input", + "items": [ + "devices[].inputs[].name", + "devices[].inputs[].reference", + "devices[].inputs[].oneStoreProductId", + "devices[].inputs[].type" + ], + "condition": { + "functionBody": "return model.devices && model.devices[arrayIndices].getInputsFromDevice === false || model.devices[arrayIndices].webApiControl === false;" + } + } + ] }, { "key": "devices[]", @@ -412,10 +429,6 @@ "devices[].disableLogInfo", "devices[].switchInfoMenu", "devices[].rebootControl", - "devices[].getInputsFromDevice", - "devices[].filterGames", - "devices[].filterApps", - "devices[].filterDlc", "devices[].refreshInterval", "devices[].volumeControl" ] diff --git a/index.js b/index.js index 2ab8793..c4694f7 100644 --- a/index.js +++ b/index.js @@ -38,35 +38,40 @@ const DEFAULT_INPUTS = [{ 'titleId': 'undefined', 'reference': 'undefined', 'oneStoreProductId': 'undefined', - 'type': 'undefined' + 'type': 'undefined', + 'contentType': 'undefined' }, { 'name': 'Television', 'titleId': 'Television', 'reference': 'Xbox.Television', 'oneStoreProductId': 'Television', - 'type': 'HDMI' + 'type': 'HDMI', + 'contentType': 'systemApp' }, { 'name': 'Dashboard', 'titleId': 'Dashboard', 'reference': 'Xbox.Dashboard_8wekyb3d8bbwe!Xbox.Dashboard.Application', 'oneStoreProductId': 'Dashboard', - 'type': 'HOME_SCREEN' + 'type': 'HOME_SCREEN', + 'contentType': 'Dashboard' }, { 'name': 'Settings', 'titleId': 'Settings', 'reference': 'Microsoft.Xbox.Settings_8wekyb3d8bbwe!Xbox.Settings.Application', 'oneStoreProductId': 'Settings', - 'type': 'HOME_SCREEN' + 'type': 'HOME_SCREEN', + 'contentType': 'Settings' }, { 'name': 'Accessory', 'titleId': 'Accessory', 'reference': 'Microsoft.XboxDevices_8wekyb3d8bbwe!App', 'oneStoreProductId': 'Accessory', - 'type': 'HOME_SCREEN' + 'type': 'HOME_SCREEN', + 'contentType': 'systemApp' } ]; @@ -141,9 +146,10 @@ class xboxTvDevice { this.volumeControl = config.volumeControl || 0; this.switchInfoMenu = config.switchInfoMenu || false; this.getInputsFromDevice = config.getInputsFromDevice || false; - this.filterGames = config.filterGames || false - this.filterApps = config.filterApps || false - this.filterDlc = config.filterDlc || false + this.filterGames = config.filterGames || false; + this.filterApps = config.filterApps || false; + this.filterSystemApps = config.filterSystemApps || false; + this.filterDlc = config.filterDlc || false; this.rebootControl = config.rebootControl || false; this.inputs = config.inputs || []; this.buttons = config.buttons || []; @@ -156,7 +162,15 @@ class xboxTvDevice { } const inputsCount = this.inputs.length; for (let j = 0; j < inputsCount; j++) { - inputsArr.push(this.inputs[j]); + const obj = { + 'name': this.inputs[1].name, + 'titleId': this.inputs[1].titleId, + 'reference': this.inputs[1].reference, + 'oneStoreProductId': this.inputs[1].oneStoreProductId, + 'type': this.inputs[1].type, + 'contentType': 'Game' + } + inputsArr.push(obj); } this.inputs = inputsArr; @@ -486,12 +500,10 @@ class xboxTvDevice { 'titleId': titleId, 'reference': aumid, 'oneStoreProductId': oneStoreProductId, - 'type': type + 'type': type, + 'contentType': contentType }; - const filterGames = this.filterGames ? (contentType != 'Game') : true; - const filterApps = this.filterApps ? (contentType != 'App') : true; - const filterDlc = this.filterDlc ? (contentType != 'Dlc') : true; - const push = (filterGames && filterApps && filterDlc) ? installedAppsArr.push(inputsObj) : false; + installedAppsArr.push(inputsObj); } this.installedAppsData = installedAppsData; @@ -641,11 +653,12 @@ class xboxTvDevice { inputsArr.push(inputsData[j]); } + //save nputs to the file const obj = JSON.stringify(inputsArr, null, 2); const writeInputs = fsPromises.writeFile(this.inputsFile, obj); this.log.debug('Device: %s %s, save inputs succesful, inputs: %s', this.host, this.name, obj); - + //device info const manufacturer = this.manufacturer; const modelName = this.modelName; const serialNumber = this.webApiEnabled ? this.serialNumber : liveid; @@ -1213,26 +1226,40 @@ class xboxTvDevice { const savedTargetVisibility = ((fs.readFileSync(this.targetVisibilityInputsFile)).length > 0) ? JSON.parse(fs.readFileSync(this.targetVisibilityInputsFile)) : {}; this.log.debug('Device: %s %s, read saved Target Visibility successful, states %s', this.host, accessoryName, savedTargetVisibility); + //check available inputs and filter costom inputs + const allInputs = (savedInputs.length > 0) ? savedInputs : this.inputs; + const inputsArr = new Array(); + const allInputsCount = allInputs.length; + const installedAppsArr = this.installedAppsArr; + for (let i = 0; i < allInputsCount; i++) { + const contentType = allInputs[i].contentType; + const filterGames = this.filterGames ? (contentType != 'Game') : true; + const filterApps = this.filterApps ? (contentType != 'App') : true; + const filterSystemApps = this.filterSystemApps ? (contentType != 'systemApp') : true; + const filterDlc = this.filterDlc ? (contentType != 'Dlc') : true; + const push = (filterGames && filterApps && filterSystemApps && filterDlc) ? inputsArr.push(allInputs[i]) : false; + } + //check available inputs and possible inputs count (max 93) - const inputs = (savedInputs.length > 0) ? savedInputs : this.inputs; + const inputs = inputsArr; const inputsCount = inputs.length; const maxInputsCount = (inputsCount < 93) ? inputsCount : 93; - for (let i = 0; i < maxInputsCount; i++) { + for (let j = 0; j < maxInputsCount; j++) { //get title Id - const inputTitleId = (inputs[i].titleId != undefined) ? inputs[i].titleId : undefined; + const inputTitleId = (inputs[j].titleId != undefined) ? inputs[j].titleId : undefined; //get input reference - const inputReference = (inputs[i].reference != undefined) ? inputs[i].reference : undefined; + const inputReference = (inputs[j].reference != undefined) ? inputs[j].reference : undefined; //get input oneStoreProductId - const inputOneStoreProductId = (inputs[i].oneStoreProductId != undefined) ? inputs[i].oneStoreProductId : undefined; + const inputOneStoreProductId = (inputs[j].oneStoreProductId != undefined) ? inputs[j].oneStoreProductId : undefined; //get input name - const inputName = (savedInputsNames[inputTitleId] != undefined) ? savedInputsNames[inputTitleId] : (savedInputsNames[inputReference] != undefined) ? savedInputsNames[inputReference] : (savedInputsNames[inputOneStoreProductId] != undefined) ? savedInputsNames[inputOneStoreProductId] : inputs[i].name; + const inputName = (savedInputsNames[inputTitleId] != undefined) ? savedInputsNames[inputTitleId] : (savedInputsNames[inputReference] != undefined) ? savedInputsNames[inputReference] : (savedInputsNames[inputOneStoreProductId] != undefined) ? savedInputsNames[inputOneStoreProductId] : inputs[j].name; //get input type - const inputType = (inputs[i].type != undefined) ? INPUT_SOURCE_TYPES.indexOf(inputs[i].type) : 10; + const inputType = (inputs[j].type != undefined) ? INPUT_SOURCE_TYPES.indexOf(inputs[j].type) : 10; //get input configured const isConfigured = 1; @@ -1241,9 +1268,9 @@ class xboxTvDevice { const currentVisibility = (savedTargetVisibility[inputTitleId] != undefined) ? savedTargetVisibility[inputTitleId] : (savedTargetVisibility[inputReference] != undefined) ? savedTargetVisibility[inputReference] : (savedTargetVisibility[inputOneStoreProductId] != undefined) ? savedTargetVisibility[inputOneStoreProductId] : 0; const targetVisibility = currentVisibility; - const inputService = new Service.InputSource(accessoryName, 'Input ' + i); + const inputService = new Service.InputSource(accessoryName, 'Input ' + j); inputService - .setCharacteristic(Characteristic.Identifier, i) + .setCharacteristic(Characteristic.Identifier, j) .setCharacteristic(Characteristic.ConfiguredName, inputName) .setCharacteristic(Characteristic.IsConfigured, isConfigured) .setCharacteristic(Characteristic.InputSourceType, inputType) @@ -1292,8 +1319,8 @@ class xboxTvDevice { this.inputsType.push(inputType); this.inputsService.push(inputService); - this.televisionService.addLinkedService(this.inputsService[i]); - accessory.addService(this.inputsService[i]); + this.televisionService.addLinkedService(this.inputsService[j]); + accessory.addService(this.inputsService[j]); } //Prepare inputs button services diff --git a/package.json b/package.json index b12d434..911518e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "displayName": "Xbox TV", "name": "homebridge-xbox-tv", - "version": "1.7.4", + "version": "1.7.5", "description": "Homebridge plugin (https://github.com/homebridge/homebridge) to control Xbox game consoles.", "license": "MIT", "author": "grzegorz914", diff --git a/sample-config.json b/sample-config.json index 144b40c..c16a3de 100644 --- a/sample-config.json +++ b/sample-config.json @@ -33,6 +33,7 @@ "getInputsFromDevice": false, "filterGames": false, "filterApps": false, + "filterSystemApps": false, "filterDlc": false, "rebootControl": false, "inputs": [{