Skip to content

Commit

Permalink
Merge branch 'main' of github.com:tomasbulva/open-sonos-controller in…
Browse files Browse the repository at this point in the history
…to main
  • Loading branch information
tomasbulva committed Jan 16, 2021
2 parents 9018846 + c8c9a59 commit 55a7d93
Show file tree
Hide file tree
Showing 23 changed files with 331 additions and 68 deletions.
Binary file removed assets/audio-blue-full.png
Binary file not shown.
Binary file modified assets/audio-bright-full.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/audio-dark-full.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed assets/audio-orange-full.png
Binary file not shown.
Binary file added assets/audio-playing-orange-full.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/audio-song-bright-full.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/audio-song-dark-full.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/tv-dialog-bright-full.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/tv-dialog-dark-full.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/tv-dialog-disabled-bright-full.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/tv-night-bright-full.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/tv-night-dark-full.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/tv-night-disabled-bright-full.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/volume-none-bright-full.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/volume-none-dark-full.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
167 changes: 135 additions & 32 deletions src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import TvArtView from "./components/tvArtView"
import CurrentTrackMetaDataView from "./components/currentTrackMetaDataView";
import PlaybackControl from "./components/playbackControl"
import RoomControl from "./components/roomControl"
import TvPlaybackControl from "./components/tvPlaybackControl"


const minSize = { width: 400, height: 700 };
Expand Down Expand Up @@ -68,10 +69,9 @@ class App extends React.Component<{}, MyState> {
async componentDidMount() {
await this.sonosDiscovery();
this.getSonosState();


setInterval(() => {
this.sonosDiscovery();
this.sonosDiscoveryOnDemand();

manager.Devices.forEach(async (d:any) => {
const result = await d.RefreshEventSubscriptions();
Expand All @@ -93,8 +93,10 @@ class App extends React.Component<{}, MyState> {
}

componentWillUnmount() {
this.sonosDiscovery();
this.unmountSonos();
}

unmountSonos() {
manager.Devices.forEach(d => {
d.CancelEvents();
d.AlarmClockService.Events.removeAllListeners(ServiceEvents.Data)
Expand All @@ -105,11 +107,24 @@ class App extends React.Component<{}, MyState> {
manager.CancelSubscription();
}

async sonosDiscoveryOnDemand(): Promise<any> {
try{
console.log(manager.Devices.length);
} catch(e) {
console.log('no devices, re-discovering');
await this.sonosDiscovery();
this.unmountSonos();
this.getSonosState();
}
}

sonosDiscovery(): Promise<boolean> {
console.log('sonosDiscovery');
return manager.InitializeWithDiscovery(10);
}

getSonosState():void {
console.log('getSonosState');
manager.Devices.forEach((d:any) => {
let mySonosDevice:MySonosDevice = {
uuid: d.uuid,
Expand All @@ -131,40 +146,52 @@ class App extends React.Component<{}, MyState> {
return { ...prevState, devices: mySonosDevices, isLoading: false };
});

d.AVTransportService.GetPositionInfo().then((data: any) => {
d.RenderingControlService.GetVolume({
InstanceID: 0,
Channel: 'Master'
}).then((data: any) => {
console.log('data.CurrentVolume', data.CurrentVolume);

this.setState(prevState => {
let mySonosDevices = {...prevState.devices};

if (
data.TrackMetaData
) {
mySonosDevices[d.uuid] = {
...mySonosDevices[d.uuid],
...{
CurrentTrackMetaData: {
Album: data.TrackMetaData.Album,
Artist: data.TrackMetaData.Artist,
Title: data.TrackMetaData.Title,
Duration: data.TrackMetaData.Duration,
}
}
};
volume: data.CurrentVolume
}
}

return {devices: mySonosDevices};
});
})
.catch((error:any) => {
console.log(error);
});


d.AVTransportService.GetPositionInfo().then((data: any) => {
this.setState(prevState => {
let mySonosDevices = {...prevState.devices};

if (
JSON.stringify(prevState?.devices[d.uuid]?.CurrentTrackMetaData?.AlbumArtUri) !== JSON.stringify(data?.CurrentTrackMetaData?.AlbumArtUri) ||
!prevState?.devices[d.uuid]?.CurrentTrackMetaData?.AlbumArtUri
data.TrackMetaData
) {
mySonosDevices[d.uuid] = {
...mySonosDevices[d.uuid],
...mySonosDevices[d.uuid],
...{
CurrentTrackMetaData: {
AlbumArtUri: data.TrackMetaData.AlbumArtUri,
Album: data.TrackMetaData?.Album,
Artist: data.TrackMetaData?.Artist,
Title: data.TrackMetaData?.Title,
Duration: data.TrackMetaData?.Duration,
AlbumArtUri: data.TrackMetaData?.AlbumArtUri,
}
}
};
}


mySonosDevices[d.uuid].isTV = (data.TrackURI && data.TrackURI.includes('spdif'));

Expand Down Expand Up @@ -194,6 +221,29 @@ class App extends React.Component<{}, MyState> {
});
});

d.RenderingControlService.Events.on('serviceEvent', (data:any) => {
console.log('RenderingControlService mute', data.Mute);
this.setState(prevState => {
let mySonosDevices = {...prevState.devices};
if (mySonosDevices[d.uuid] && mySonosDevices[d.uuid].name) {
mySonosDevices[d.uuid] = {
...(
mySonosDevices[d.uuid] || {}
),
...{
isTvDialogOn: data?.DialogLevel === '1',
isTvNightOn: data?.NightMode === true,
isMute: data?.Mute?.Master,
}
};

return { ...prevState, devices: mySonosDevices};
}

return prevState;
});
});

d.AVTransportService.Events.on('serviceEvent', (data:any) => {
this.setState(prevState => {
let mySonosDevices = {...prevState.devices};
Expand All @@ -212,17 +262,17 @@ class App extends React.Component<{}, MyState> {

if (
data.CurrentTrackMetaData &&
JSON.stringify(prevState.devices[d.uuid].CurrentTrackMetaData.Title) !== JSON.stringify(data.CurrentTrackMetaData.Title)
JSON.stringify(prevState.devices[d.uuid].CurrentTrackMetaData?.Title) !== JSON.stringify(data.CurrentTrackMetaData?.Title)
) {
mySonosDevices[d.uuid] = {
...mySonosDevices[d.uuid],
...{
CurrentTrackMetaData: {
Album: data.CurrentTrackMetaData.Album,
Artist: data.CurrentTrackMetaData.Artist,
AlbumArtUri: data.CurrentTrackMetaData.AlbumArtUri,
Title: data.CurrentTrackMetaData.Title,
Duration: data.CurrentTrackMetaData.Duration,
Album: data.CurrentTrackMetaData?.Album,
Artist: data.CurrentTrackMetaData?.Artist,
AlbumArtUri: data.CurrentTrackMetaData?.AlbumArtUri,
Title: data.CurrentTrackMetaData?.Title,
Duration: data.CurrentTrackMetaData?.Duration,
}
}
};
Expand All @@ -245,7 +295,7 @@ class App extends React.Component<{}, MyState> {
}

async handlePlay (): Promise<any> {
await this.sonosDiscovery();
await this.sonosDiscoveryOnDemand();

const { selectedDeviceUuid, devices } = this.state;
manager.Devices.forEach((d:any) => {
Expand All @@ -256,7 +306,7 @@ class App extends React.Component<{}, MyState> {
}

async handlePause (): Promise<any> {
await this.sonosDiscovery();
await this.sonosDiscoveryOnDemand();

const { selectedDeviceUuid, devices } = this.state;
manager.Devices.forEach((d:any) => {
Expand All @@ -267,7 +317,7 @@ class App extends React.Component<{}, MyState> {
}

async handleNext (): Promise<any> {
await this.sonosDiscovery();
await this.sonosDiscoveryOnDemand();

const { selectedDeviceUuid, devices } = this.state;
manager.Devices.forEach((d:any) => {
Expand All @@ -277,9 +327,8 @@ class App extends React.Component<{}, MyState> {
});
}


async handlePrev (): Promise<any> {
await this.sonosDiscovery();
await this.sonosDiscoveryOnDemand();

const { selectedDeviceUuid, devices } = this.state;
manager.Devices.forEach((d:any) => {
Expand All @@ -290,7 +339,7 @@ class App extends React.Component<{}, MyState> {
}

async setVolume (volume: number):Promise<any> {
await this.sonosDiscovery();
await this.sonosDiscoveryOnDemand();

const { selectedDeviceUuid } = this.state;

Expand All @@ -301,6 +350,49 @@ class App extends React.Component<{}, MyState> {
});
}

async setDialog (): Promise<any> {
await this.sonosDiscoveryOnDemand();

const { selectedDeviceUuid, devices } = this.state;

// console.log('devices[selectedDeviceUuid].isTvDialogOn', devices[selectedDeviceUuid].isTvDialogOn);

manager.Devices.forEach((d:any) => {
if (d.uuid === selectedDeviceUuid) {
d.SetSpeechEnhancement(devices[selectedDeviceUuid].isTvDialogOn ? false : true);
}
});
}

async setNight (): Promise<any> {
await this.sonosDiscoveryOnDemand();

const { selectedDeviceUuid, devices } = this.state;
manager.Devices.forEach((d:any) => {
if (d.uuid === selectedDeviceUuid) {
d.SetNightMode(devices[selectedDeviceUuid].isTvNightOn ? false : true);
}
});
}

async setMute (): Promise<any> {
await this.sonosDiscoveryOnDemand();

const { selectedDeviceUuid, devices } = this.state;

// console.log('!devices[selectedDeviceUuid].isMute', !devices[selectedDeviceUuid].isMute)

manager.Devices.forEach((d:any) => {
if (d.uuid === selectedDeviceUuid) {
d.RenderingControlService.SetMute({
InstanceID: 0,
Channel: 'Master',
DesiredMute: !devices[selectedDeviceUuid].isMute
});
}
});
}

selectHandler (uuid: string):void {
this.setState({selectedDeviceUuid: uuid});
}
Expand Down Expand Up @@ -354,11 +446,22 @@ class App extends React.Component<{}, MyState> {
<View id="mainTvControl">
<TvArtView />
<CurrentTrackMetaDataView currentTrackMetaData={{Album: "", Artist: "", Title: "TV"}} />
<TvPlaybackControl
isTvDialogOn={devices[selectedDeviceUuid].isTvDialogOn}
isTvNightOn={devices[selectedDeviceUuid].isTvNightOn}
dialog={this.setDialog.bind(this)}
night={this.setNight.bind(this)}
/>
</View>
)
}
<View id="mainVolumeControl">
<VolumeSlider volume={devices[selectedDeviceUuid].volume} setVolume={this.setVolume.bind(this)} />
<VolumeSlider
volume={devices[selectedDeviceUuid].volume}
setVolume={this.setVolume.bind(this)}
isMute={devices[selectedDeviceUuid].isMute}
mute={this.setMute.bind(this)}
/>
</View>
<View id="spacer" />

Expand Down
2 changes: 2 additions & 0 deletions src/components/albumArtView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ interface AlbumArtViewProps {

export default function AlbumArtView(props: AlbumArtViewProps) {
const { albumArtUri } = props;

console.log('albumArtUri', albumArtUri);

return albumArtUri ? (
<View styleSheet={styleSheet} id="cover">
Expand Down
40 changes: 26 additions & 14 deletions src/components/currentTrackMetaDataView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,34 +15,46 @@ interface CurrentTrackMetaDataViewProps {
export default function CurrentTrackMetaDataView(props: CurrentTrackMetaDataViewProps) {
const { currentTrackMetaData } = props;
return (
<View id="trackData" styleSheet={styleSheet}>
<Text id="Title" wordWrap={true}>{unescape(currentTrackMetaData.Title || 'Unknown')}</Text>
<Text id="Artist" wordWrap={true}>{unescape(currentTrackMetaData.Artist || '')}{currentTrackMetaData.Album ? ` - ${currentTrackMetaData.Album}` : ''}</Text>
</View>
<View id="trackData" styleSheet={styleSheet}>
<View id="spacer-top" />
<Text id="Title" wordWrap={true}>{`${ unescape( currentTrackMetaData?.Title || 'Unknown' ) }<br/><small><font color="#afafaf">${ unescape(currentTrackMetaData?.Artist || '') }${currentTrackMetaData?.Album ? ` - ${currentTrackMetaData?.Album}` : ''}</font></small>`}</Text>
<View id="spacer" />
</View>
);
}

const styleSheet = `
#spacer-top, #spacer {
border: 0px solid red;
}
#trackData, #Title, #Artist {
border: 0px solid green;
}
#trackData {
flex: 1 1 1px;
width: '360px';
padding: '0px';
margin: '0px';
}
#spacer-top {
flex: 1 1 15px;
height: 15px;
}
#spacer {
flex: 1 1 20px;
height: 20px;
}
#Title {
color: 'white';
font-size: 20px;
margin-top: '10px';
margin-bottom: '5px';
padding: '0px';
width: '360px';
}
#Artist {
color: white;
font-size: 15px;
margin-top: '0px';
margin-bottom: '5px';
margin-bottom: '0px';
padding: '0px';
width: '360px';
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/roomControl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {

import { unescape } from "../utils/unescape";

import audioOrangeIconPath from "../../assets/audio-orange-full.png";
import audioOrangeIconPath from "../../assets/audio-playing-orange-full.png";
const audioOrangeIcon = new QIcon(audioOrangeIconPath);

import audioIconPath from "../../assets/audio-bright-full.png";
Expand Down
4 changes: 3 additions & 1 deletion src/components/tvArtView.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React, { useRef } from "react";
import { Image, View } from "@nodegui/react-nodegui";

import tvIconPath from "../../assets/tv-gray-full.png";

import {
AspectRatioMode
} from "@nodegui/nodegui";
Expand All @@ -11,7 +13,7 @@ export default function AlbumArtView() {
<Image
id="tvIcon"
aspectRatioMode={AspectRatioMode.KeepAspectRatio}
src="assets/tv-gray-full.png"
src={tvIconPath}
/>
</View>
);
Expand Down
Loading

0 comments on commit 55a7d93

Please sign in to comment.