-
-
Notifications
You must be signed in to change notification settings - Fork 21
/
MMM-Sonos.js
executable file
·116 lines (114 loc) · 3.67 KB
/
MMM-Sonos.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/* Magic Mirror
* Module: MagicMirror-Sonos-Module
*
* By Christopher Fenner https://github.com/CFenner
* MIT Licensed.
*/
Module.register('MMM-Sonos', {
defaults: {
showStoppedRoom: true,
showAlbumArt: true,
albumArtLocation: 'right',
showRoomName: true,
animationSpeed: 1000,
updateInterval: 0.5, // every 0.5 minutes
apiBase: 'http://localhost',
apiPort: 5005,
apiEndpoint: 'zones',
exclude: []
},
roomList: [],
start: function () {
Log.info('Starting module: ' + this.name)
this.update()
// refresh every x minutes
setInterval(
this.update.bind(this),
this.config.updateInterval * 60 * 1000)
},
update: function () {
this.sendSocketNotification(
'SONOS_UPDATE',
this.config.apiBase + ':' + this.config.apiPort + '/' + this.config.apiEndpoint)
},
getRoomName: function (room) {
const roomList = []
if (room.members.length > 1) {
room.members.forEach(function (member) {
if (!this.isRoomExcluded(member.roomName)) { roomList.push(member.roomName) }
}.bind(this))
} else {
if (!this.isRoomExcluded(room.coordinator.roomName)) { roomList.push(room.coordinator.roomName) }
}
return roomList.join(', ')
},
isRoomExcluded: function (roomName) {
return this.config.exclude.indexOf(roomName) !== -1
},
isInTVMode: function (artist, track, cover) {
// if Sonos Playbar is in TV mode, no title is provided and therefore the room should not be displayed
return (artist && artist.length) === 0 && (track && track.length) === 0 && (cover && cover.length) === 0
},
updateRoomList: function (data) {
const roomList = []
data.forEach(function (item) {
const roomName = this.getRoomName(item)
if (roomName !== '') {
const currentTrack = item.coordinator.state.currentTrack
let artist = currentTrack.artist
let track = currentTrack.title
let cover = currentTrack.absoluteAlbumArtUri
// var streamInfo = currentTrack.streamInfo;
// var type = currentTrack.type;
// clean data
artist = artist ? artist.trim() : ''
track = track ? track.trim() : ''
cover = cover ? cover.trim() : ''
track = track === currentTrack.uri ? '' : track
// remove stream URL from title
if (currentTrack.trackUri && currentTrack.trackUri.includes(track)) {
track = ''
}
roomList.push({
name: roomName,
state: this.isInTVMode(artist, track, cover) ? 'TV' : item.coordinator.state.playbackState,
artist: artist,
track: track,
albumArt: cover
})
}
}.bind(this))
this.loaded = true
if (JSON.stringify(this.roomList) === JSON.stringify(roomList)) {
return
}
this.roomList = roomList
this.updateDom(this.config.animationSpeed)
},
getStyles: function () {
return [`${this.name}.css`]
},
getTemplate: function () {
return `${this.name}.njk`
},
getTemplateData: function () {
return {
flip: this.data.position.startsWith('left'),
loaded: this.loaded,
showAlbumArtRight:
this.config.showAlbumArt && this.config.albumArtLocation !== 'left',
showAlbumArtLeft:
this.config.showAlbumArt && this.config.albumArtLocation === 'left',
showRoomName: this.config.showRoomName,
showStoppedRoom: this.config.showStoppedRoom,
roomList: this.roomList,
labelLoading: this.translate('LOADING')
}
},
socketNotificationReceived: function (notification, payload) {
if (notification === 'SONOS_DATA') {
Log.debug('received SONOS_DATA')
this.updateRoomList(payload)
}
}
})