Skip to content

Commit

Permalink
release v3.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
grzegorz914 committed Aug 23, 2024
1 parent 31ec69c commit cb32fb0
Show file tree
Hide file tree
Showing 8 changed files with 143 additions and 94 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### NOTE

### After update to 2.x.x the plugin settings (xboxLiveId) need to be updated

### After update to v3.0.0 RESTFull and MQTT config settings need to be updated

## [3.1.0] - (23.08.2024)

## Changes

- add control over RESTFul POST JSON Object
- cleanup

## [3.0.2] - (18.08.2024)

## Changes
Expand Down
40 changes: 25 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,22 +140,32 @@ Homebridge plugin for Microsoft game Consoles. Tested with Xbox One X/S and Xbox

### RESTFul Integration

* Request: `http//homebridge_ip_address:port/path`.
* Path: `info`, `state`, `consoleslist`, `profile`, `apps`, `storages`, `status`.
* Respone as JSON object.
* POST data as a JSON Object `{Power: true}`

| Method | URL | Path | Response | Type |
| --- | --- | --- | --- | --- |
| GET | `http//ip:port` | `info`, `state`, `consoleslist`, `profile`, `apps`, `storages`, `status`. | `{"power": true, "app": Xbox.Dashboard_8wekyb3d8bbwe!Xbox.Dashboard.Application}` | JSON object. |

| Method | URL | Key | Value | Type | Description |
| --- | --- | --- | --- | --- | --- |
| POST | `http//ip:port` | `Power` | `true`, `false` | boolean | Power state. |
| | `http//ip:port` | `App` | `Xbox.Dashboard_8wekyb3d8bbwe!Xbox.Dashboard.Application` | string | Set app. |
| | `http//ip:port` | `RcControl` | `fastForward` | string | Send RC command. |
| | `http//ip:port` | `Volume` | `up`, `down` | string | Set volume. |
| | `http//ip:port` | `Mute` | `true`, `false` | boolean | Set mute. |

### MQTT Integration

| Direction | Topic | Message | Payload Data |
| --- | --- | --- | --- |
| Publish | `Info`, `State`, `Consoles List`, `Profile`, `Apps`, `Storages`, `Status` | `{"power": true, "app": Xbox.Dashboard_8wekyb3d8bbwe!Xbox.Dashboard.Application}` | JSON object. |
| Subscribe | `Set` | `{"Power": true}` | JSON object. |
* Subscribe data as a JSON Object `{App: "Xbox.Dashboard_8wekyb3d8bbwe!Xbox.Dashboard.Application"}`

| Subscribe | Key | Value | Type | Description |
| --- | --- | --- | --- | --- |
| Xbox | | | | |
| | `Power` | `true`, `false` | boolean | Power state. |
| | `App` | `Xbox.Dashboard_8wekyb3d8bbwe!Xbox.Dashboard.Application` | string | Set app. |
| | `RcControl` | `fastForward` | string | Send RC command. |
| | `Volume` | `up`, `down` | string | Set volume. |
| | `Mute` | `true`, `false` | boolean | Set mute. |
| Method | Topic | Message | Type |
| --- | --- | --- | --- |
| Publish | `Info`, `State`, `Consoles List`, `Profile`, `Apps`, `Storages`, `Status` | `{"power": true, "app": Xbox.Dashboard_8wekyb3d8bbwe!Xbox.Dashboard.Application}` | JSON object. |

| Method | Topic | Key | Value | Type | Description |
| --- | --- | --- | --- | --- | --- |
| Subscribe | `Set` | `Power` | `true`, `false` | boolean | Power state. |
| | `Set` | `App` | `Xbox.Dashboard_8wekyb3d8bbwe!Xbox.Dashboard.Application` | string | Set app. |
| | `Set` | `RcControl` | `fastForward` | string | Send RC command. |
| | `Set` | `Volume` | `up`, `down` | string | Set volume. |
| | `Set` | `Mute` | `true`, `false` | boolean | Set mute. |
3 changes: 3 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ class XboxPlatform {
.on('devInfo', (devInfo) => {
log.info(devInfo);
})
.on('success', (message) => {
log.success(`Device: ${deviceHost} ${deviceName}, ${message}`);
})
.on('message', (message) => {
log.info(`Device: ${deviceHost} ${deviceName}, ${message}`);
})
Expand Down
18 changes: 9 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"displayName": "Xbox TV",
"name": "homebridge-xbox-tv",
"version": "3.0.4",
"version": "3.1.0",
"description": "Homebridge plugin to control Xbox game consoles.",
"license": "MIT",
"author": "grzegorz914",
Expand Down Expand Up @@ -29,7 +29,7 @@
],
"engines": {
"node": ">=18.0.0",
"homebridge": ">=1.6.0"
"homebridge": ">=1.8.0"
},
"dependencies": {
"@homebridge/plugin-ui-utils": "^1.0.3",
Expand All @@ -40,7 +40,7 @@
"uuid": "^10.0.0",
"ping": "^0.4.4",
"express": "^4.19.2",
"axios": "^1.7.4"
"axios": "^1.7.5"
},
"keywords": [
"homebridge",
Expand Down
2 changes: 1 addition & 1 deletion src/mqtt.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class Mqtt extends EventEmitter {
const emitDebug = config.debug ? this.emit('debug', `MQTT Received topic: ${topic}, message: ${JSON.stringify(subscribedMessage, null, 2)}`) : false;
const key = Object.keys(subscribedMessage)[0];
const value = Object.values(subscribedMessage)[0];
this.emit('subscribedMessage', key, value);
this.emit('set', key, value);
} catch (error) {
this.emit('error', `MQTT Parse message error: ${error}`);
};
Expand Down
15 changes: 15 additions & 0 deletions src/restful.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class RestFul extends EventEmitter {
try {
const restFul = express();
restFul.set('json spaces', 2);
restFul.use(express.json());
restFul.get('/info', (req, res) => { res.json(this.restFulData.info) });
restFul.get('/state', (req, res) => { res.json(this.restFulData.state) });
restFul.get('/consoleslist', (req, res) => { res.json(this.restFulData.consoleslist) });
Expand All @@ -32,6 +33,20 @@ class RestFul extends EventEmitter {
restFul.get('/storages', (req, res) => { res.json(this.restFulData.storages) });
restFul.get('/status', (req, res) => { res.json(this.restFulData.status) });

//post data
restFul.post('/', (req, res) => {
try {
const obj = req.body;
const emitDebug = this.restFulDebug ? this.emit('debug', `RESTFul post data: ${JSON.stringify(obj, null, 2)}`) : false;
const key = Object.keys(obj)[0];
const value = Object.values(obj)[0];
this.emit('set', key, value);
res.send('OK');
} catch (error) {
this.emit('error', `RESTFul Parse object error: ${error}`);
};
});

restFul.listen(this.restFulPort, () => {
this.emit('connected', `RESTful started on port: ${this.restFulPort}`)
});
Expand Down
145 changes: 79 additions & 66 deletions src/xboxdevice.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,10 @@ class XboxDevice extends EventEmitter {
this.volumeControlNamePrefix = device.volumeControlNamePrefix || false;
this.volumeControlName = device.volumeControlName || 'Volume';

//external integration
//restRul
//external integrations
const restFul = device.restFul ?? {};
const restFulEnabled = restFul.enable || false;
this.restFulConnected = false;

//mqtt
const mqtt = device.mqtt ?? {};
const mqttEnabled = mqtt.enable || false;
this.mqttConnected = false;

//accessory services
Expand Down Expand Up @@ -324,6 +319,7 @@ class XboxDevice extends EventEmitter {
})
.on('prepareAccessory', async () => {
//RESTFul server
const restFulEnabled = restFul.enable || false;
if (restFulEnabled) {
this.restFul = new RestFul({
port: restFul.port || 3000,
Expand All @@ -332,8 +328,15 @@ class XboxDevice extends EventEmitter {

this.restFul.on('connected', (message) => {
this.restFulConnected = true;
this.emit('message', message);
this.emit('success', message);
})
.on('set', async (key, value) => {
try {
await this.setOverExternalIntegration('RESTFul', key, value);
} catch (error) {
this.emit('warn', `RESTFul set error: ${error}`);
};
})
.on('debug', (debug) => {
this.emit('debug', debug);
})
Expand All @@ -343,6 +346,7 @@ class XboxDevice extends EventEmitter {
}

//mqtt client
const mqttEnabled = mqtt.enable || false;
if (mqttEnabled) {
this.mqtt = new Mqtt({
host: mqtt.host,
Expand All @@ -356,70 +360,16 @@ class XboxDevice extends EventEmitter {

this.mqtt.on('connected', (message) => {
this.mqttConnected = true;
this.emit('message', message);
this.emit('success', message);
})
.on('subscribed', (message) => {
this.emit('message', message);
this.emit('success', message);
})
.on('subscribedMessage', async (key, value) => {
.on('set', async (key, value) => {
try {
switch (key) {
case 'Power':
switch (this.webApiPowerOnOff) {
case true:
switch (value) {
case true: //off
await this.xboxWebApi.send('Power', 'WakeUp');
break;
case false: //on
await this.xboxWebApi.send('Power', 'TurnOff');
break;
}
break;
case false:
switch (value) {
case true: //off
await this.xboxLocalApi.powerOff();
break;
case false: //on
await this.xboxLocalApi.powerOn();
break;
}
}
break;
case 'App':
const payload = [{ 'oneStoreProductId': value }];
await this.xboxWebApi.send('Shell', 'ActivateApplicationWithOneStoreProductId', payload);
break;
case 'Volume':
switch (value) {
case 'up': //Up
await this.xboxWebApi.send('Volume', 'Up');
break;
case 'down': //Down
await this.xboxWebApi.send('Volume', 'Down');
break;
}
break;
case 'Mute':
switch (value) {
case true: //Mute
await this.xboxWebApi.send('Audio', 'Mute');
break;
case false: //Unmute;
await this.xboxWebApi.send('Audio', 'Unmute');
break;
}
break;
case 'RcControl':
await this.xboxWebApi.send('Shell', 'InjectKey', [{ 'keyType': value }]);
break;
default:
this.emit('message', `MQTT Received unknown key: ${key}, value: ${value}`);
break;
};
await this.setOverExternalIntegration('MQTT', key, value);
} catch (error) {
this.emit('warn', `MQTT send error: ${error}.`);
this.emit('warn', `MQTT set error: ${error}.`);
};
})
.on('debug', (debug) => {
Expand Down Expand Up @@ -535,6 +485,69 @@ class XboxDevice extends EventEmitter {
};
}

async setOverExternalIntegration(integration, key, value) {
try {
let set = false
switch (key) {
case 'Power':
switch (this.webApiPowerOnOff) {
case true:
switch (value) {
case true: //off
set = await this.xboxWebApi.send('Power', 'WakeUp');
break;
case false: //on
set = await this.xboxWebApi.send('Power', 'TurnOff');
break;
}
break;
case false:
switch (value) {
case true: //off
set = await this.xboxLocalApi.powerOff();
break;
case false: //on
set = await this.xboxLocalApi.powerOn();
break;
}
}
break;
case 'App':
const payload = [{ 'oneStoreProductId': value }];
set = await this.xboxWebApi.send('Shell', 'ActivateApplicationWithOneStoreProductId', payload);
break;
case 'Volume':
switch (value) {
case 'up': //Up
set = await this.xboxWebApi.send('Volume', 'Up');
break;
case 'down': //Down
set = await this.xboxWebApi.send('Volume', 'Down');
break;
}
break;
case 'Mute':
switch (value) {
case true: //Mute
set = await this.xboxWebApi.send('Audio', 'Mute');
break;
case false: //Unmute;
set = await this.xboxWebApi.send('Audio', 'Unmute');
break;
}
break;
case 'RcControl':
set = await this.xboxWebApi.send('Shell', 'InjectKey', [{ 'keyType': value }]);
break;
default:
this.emit('warn', `${integration}, received key: ${key}, value: ${value}`);
break;
};
return set;
} catch (error) {
throw new Error(`${integration} set key: ${key}, value: ${value}, error: ${error}`);
};
}

//Prepare accessory
async prepareAccessory() {
Expand Down

0 comments on commit cb32fb0

Please sign in to comment.