diff --git a/MMM-HomeAssistant-Touch.css b/MMM-HomeAssistant-Touch.css index 4ce4e7d..fe4e678 100644 --- a/MMM-HomeAssistant-Touch.css +++ b/MMM-HomeAssistant-Touch.css @@ -28,6 +28,7 @@ padding: 0; padding-left: .5rem; height: 8rem; + width: 7.5rem; display: flex; } #MMM-HomeAssistant-Touch .ha-entity.ha-cover .title{ @@ -62,4 +63,48 @@ body { cursor: default; +} + +.ha-media_player { + background-size: cover; +} + +.ha-media_player .title { + mix-blend-mode: difference; + height: 6rem; +} + +.ha-media_player .media_player_control { + width: 8.2rem; + height: 1.6rem; + margin-left: -10px; + border-bottom-left-radius: 0.5rem; + border-bottom-right-radius: 0.5rem; + display: flex; +} + +.ha-media_player .media_player_control div { + display: block; + flex-grow: 1; + border: 1px solid grey; + display: inline; +} + +.ha-media_player .media_player_control div i.fas { + display: block; + margin-top: 3px; + mix-blend-mode: color-dodge; +} + +.ha-media_player .media_player_control div:nth-child(1) { + border-bottom-left-radius: 0.5rem; +} + +.ha-media_player .media_player_control div:nth-child(2n) { + border-right: 0; + border-left: 0; +} + +.ha-media_player .media_player_control div:nth-last-child(1) { + border-bottom-right-radius: 0.5rem; } \ No newline at end of file diff --git a/MMM-HomeAssistant-Touch.js b/MMM-HomeAssistant-Touch.js index 0fadb89..1968a66 100644 --- a/MMM-HomeAssistant-Touch.js +++ b/MMM-HomeAssistant-Touch.js @@ -12,7 +12,7 @@ Module.register("MMM-HomeAssistant-Touch", { getDom, socketNotificationReceived, getStyles: function () { - return [this.file("MMM-HomeAssistant-Touch.css")]; + return [this.file("MMM-HomeAssistant-Touch.css"), "font-awesome.css"]; }, getScripts: function () { return [ diff --git a/UIClasses/MediaPlayer.js b/UIClasses/MediaPlayer.js index 95efea0..5c917bf 100644 --- a/UIClasses/MediaPlayer.js +++ b/UIClasses/MediaPlayer.js @@ -1,20 +1,58 @@ -class MediaPlayer extends Slider { - updateState(state) { - console.log(state) - this.name = (state.attributes || {}).friendly_name || this.id; - this.state = state.attributes.volume_level * 100; - this.render(); - } - - onSliderMove(event) { - super.onSliderMove(event) - this.sendNewState() - } +class MediaPlayer extends Base { + updateState(state) { + this.name = (state.attributes || {}).media_title || (state.attributes || {}).friendly_name || this.id; + this.state = state; + this.render(); + } - sendNewState() { - this.mm.sendSocketNotification("SET_MEDIAPLAYER_VOLUME", { - entity: this.id, - volume_level: this.sliderState / 100, - }); - } -} \ No newline at end of file + getControls() { + const controlDiv = document.createElement("div"); + controlDiv.id = `control-${this.id}`; + controlDiv.classList.add("media_player_control"); + + const previous = this.getButton("step-backward"); + previous.onclick = () => { + this.mm.sendSocketNotification("MEDIA_PLAYER_PREVIOUS", { + entity: this.id, + }); + }; + controlDiv.appendChild(previous); + + let playPause = this.getButton("play"); + if (this.state.state === "playing") { + playPause = this.getButton("pause"); + } + playPause.onclick = () => { + this.mm.sendSocketNotification("MEDIA_PLAYER_PLAYPAUSE", { + entity: this.id, + }); + }; + controlDiv.appendChild(playPause); + + const next = this.getButton("step-forward"); + next.onclick = () => { + this.mm.sendSocketNotification("MEDIA_PLAYER_NEXT", { + entity: this.id, + }); + }; + controlDiv.appendChild(next); + + return controlDiv; + } + + getButton(icon) { + const button = document.createElement("div"); + button.innerHTML = ``; + return button; + } + + render() { + super.render(); + const container = document.getElementById(this.id); + if (container) { + container.appendChild(this.getControls()); + } + console.log(this.state) + container.style.backgroundImage = `url("${this.mm.config.host}:${this.mm.config.port}${this.state.attributes.entity_picture}")` + } +} diff --git a/node_helper.js b/node_helper.js index 0d2e62e..003b2a3 100644 --- a/node_helper.js +++ b/node_helper.js @@ -12,6 +12,9 @@ module.exports = NodeHelper.create({ toggleState, setCoverPosition, setMediaPlayerVolume, + mediaPlayerPlayPause, + mediaPlayerNext, + mediaPlayerPrevious, onStateChangedEvent, }); @@ -54,6 +57,15 @@ function socketNotificationReceived(notification, payload) { case "SET_MEDIAPLAYER_VOLUME": this.setMediaPlayerVolume(payload); break; + case "MEDIA_PLAYER_PLAYPAUSE": + this.mediaPlayerPlayPause(payload); + break; + case "MEDIA_PLAYER_PREVIOUS": + this.mediaPlayerPrevious(payload); + break; + case "MEDIA_PLAYER_NEXT": + this.mediaPlayerNext(payload); + break; } } @@ -134,6 +146,31 @@ async function setMediaPlayerVolume(payload) { }); } +async function mediaPlayerPlayPause(payload) { + this.logger.debug(`Play/Pause for media_player ${payload.entity}`); + const hass = this.connections[payload.identifier].hass; + await hass.services.call("media_play_pause", "media_player", { + entity_id: payload.entity + }); +} + +async function mediaPlayerNext(payload) { + this.logger.debug(`Next for media_player ${payload.entity}`); + const hass = this.connections[payload.identifier].hass; + await hass.services.call("media_next_track", "media_player", { + entity_id: payload.entity + }); +} + +async function mediaPlayerPrevious(payload) { + this.logger.debug(`Next for media_player ${payload.entity}`); + const hass = this.connections[payload.identifier].hass; + await hass.services.call("media_previous_track", "media_player", { + entity_id: payload.entity + }); +} + + function onStateChangedEvent(event) { //this.logger.debug(`Got state change for ${event.data.entity_id}`); for (const connection in this.connections) {