Skip to content
This repository has been archived by the owner on Oct 23, 2024. It is now read-only.

Commit

Permalink
feat: make switch optional with config option
Browse files Browse the repository at this point in the history
  • Loading branch information
apexad committed Dec 7, 2020
1 parent 8fa2bc1 commit 66475cb
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 18 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
[![npm](https://badgen.net/npm/dt/homebridge-airport-express-playing)](https://www.npmjs.com/package/homebridge-airport-express-playing)
[![donate](https://badgen.net/badge/donate/paypal/91BE09)](https://www.paypal.me/apexadm)

[Homebridge](https://github.com/homebridge/homebridge) plugin that creates a smart speaker accessory that shows playing/paused for airport express devices.
[Homebridge](https://github.com/homebridge/homebridge) plugin that creates a smart speaker accessory that shows playing/paused for airport express devices. Also creates a switch that can be used to trigger home automations.

## Configuration
This easiest way to use this plugin is to use [homebridge-config-ui-x](https://www.npmjs.com/package/homebridge-config-ui-x).
Expand All @@ -15,9 +15,11 @@ To configure manually, add to the `platforms` section of Homebridge's `config.js
```json
{
"platform": "AirportExpressPlaying",
"name": "Airport Express Playing Platform"
"name": "Airport Express Playing Platform",
"showSwitch": true
}
```

## Sponsors
[mbmccormick](https://github.com/mbmccormick)
[jsiegenthaler](https://github.com/jsiegenthaler) - orginal idea to use airport express txt record [posted to reddit](https://www.reddit.com/r/homebridge/comments/jxt9le/added_a_switch_in_homebridge_to_show_if_airport/)
2 changes: 1 addition & 1 deletion config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"default": "Airport Express Playing Platform",
"required": true
},
"showSwitches": {
"showSwitch": {
"title": "Show Switch (for home automations)",
"type": "boolean",
"default": true,
Expand Down
30 changes: 15 additions & 15 deletions src/platformAccessory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export default class AirportExpress implements AccessoryPlugin {
constructor(hap: HAP, mdns: any, log: Logging, config: PlatformConfig, data: mDNSReply) {
this.log = log;
this.name = data.fullname.replace('._airplay._tcp.local', '');
this.showSwitch = config.showSwitches || true;
this.showSwitch = config.showSwitch || true;
this.serialNumber = data.txt.find((str) => str.indexOf('serialNumber') > -1)?.replace('serialNumber=', '') || '';
this.hap = hap;
this.mdns = mdns;
Expand All @@ -41,9 +41,7 @@ export default class AirportExpress implements AccessoryPlugin {
.getCharacteristic(this.hap.Characteristic.TargetMediaState) /* ignore attempts to set media state */
.on(CharacteristicEventTypes.SET, (state: CharacteristicValue, callback: CharacteristicSetCallback) => callback(null));

if(this.showSwitch) {
this.switchService = new hap.Service.Switch(this.name);
}
if(this.showSwitch) { this.switchService = new hap.Service.Switch(this.name); }

this.informationService = new this.hap.Service.AccessoryInformation()
.setCharacteristic(this.hap.Characteristic.Manufacturer, 'Apple Inc.')
Expand All @@ -57,23 +55,25 @@ export default class AirportExpress implements AccessoryPlugin {
}

convertMediaState(mDNS_TXT_record: Array<string>) {
let playState = this.hap.Characteristic.CurrentMediaState.STOP;
const bit11 = parseInt(((parseInt(mDNS_TXT_record.find((row: string) => row.indexOf('flags') > -1)!.replace('flags=', ''), 16).toString(2)).padStart(11, '0')).charAt(0));
if (bit11 === 0) {
playState = this.hap.Characteristic.CurrentMediaState.PAUSE;
return this.hap.Characteristic.CurrentMediaState.PAUSE;
} else if (bit11 === 1) { /* bit11 correspponds to playing https://github.com/openairplay/airplay-spec/blob/master/src/status_flags.md */
playState = this.hap.Characteristic.CurrentMediaState.PLAY;
return this.hap.Characteristic.CurrentMediaState.PLAY;
}
return playState;
return this.hap.Characteristic.CurrentMediaState.STOP;
}

updateMediaState() {
this.log.debug(`Updating Airport Exrpess with serial number ${this.serialNumber}`);
const mdnsBrowser = this.mdns.createBrowser(this.mdns.tcp("airplay"));

mdnsBrowser.on('ready', () => mdnsBrowser.discover());
mdnsBrowser.on('update', (data: mDNSReply) => {
const foundSerialNumber = data.txt.find((str) => str.indexOf('serialNumber') > -1)?.replace('serialNumber=', '');

if (data.txt.includes('model=AirPort10,115') && foundSerialNumber && this.serialNumber === foundSerialNumber) {
this.log.debug(`txt record contents: ${data.txt}`)
this.setMediaState(this.convertMediaState(data.txt));
mdnsBrowser.stop();
}
Expand All @@ -84,16 +84,16 @@ export default class AirportExpress implements AccessoryPlugin {
this.speakerService
.setCharacteristic(this.hap.Characteristic.TargetMediaState, state)
.setCharacteristic(this.hap.Characteristic.CurrentMediaState, state);

if (this.showSwitch) {
this.switchService
.setCharacteristic(
this.hap.Characteristic.On,
state ===this.hap.Characteristic.CurrentMediaState.PLAY
? true
: false
)
.setCharacteristic(this.hap.Characteristic.On, state ===this.hap.Characteristic.CurrentMediaState.PLAY ? true : false)
}
}

getServices(): Service[] { return [ this.informationService, this.speakerService, this.switchService ]; }
getServices(): Service[] {
const services = [ this.informationService, this.speakerService ];
if (this.showSwitch) { services.push(this.switchService); }
return services;
}
}

0 comments on commit 66475cb

Please sign in to comment.