2019-05-02 12:35:22 +00:00
|
|
|
"""Support for Panasonic Blu-ray players."""
|
2018-11-21 13:22:24 +00:00
|
|
|
from datetime import timedelta
|
|
|
|
|
2019-10-14 21:17:08 +00:00
|
|
|
from panacotta import PanasonicBD
|
2018-11-21 13:22:24 +00:00
|
|
|
import voluptuous as vol
|
|
|
|
|
2020-04-25 16:00:57 +00:00
|
|
|
from homeassistant.components.media_player import PLATFORM_SCHEMA, MediaPlayerEntity
|
2019-02-08 22:18:18 +00:00
|
|
|
from homeassistant.components.media_player.const import (
|
2019-07-31 19:25:30 +00:00
|
|
|
SUPPORT_PAUSE,
|
|
|
|
SUPPORT_PLAY,
|
|
|
|
SUPPORT_STOP,
|
|
|
|
SUPPORT_TURN_OFF,
|
|
|
|
SUPPORT_TURN_ON,
|
|
|
|
)
|
2018-11-21 13:22:24 +00:00
|
|
|
from homeassistant.const import (
|
2019-07-31 19:25:30 +00:00
|
|
|
CONF_HOST,
|
|
|
|
CONF_NAME,
|
|
|
|
STATE_IDLE,
|
|
|
|
STATE_OFF,
|
|
|
|
STATE_PLAYING,
|
|
|
|
)
|
2018-11-21 13:22:24 +00:00
|
|
|
import homeassistant.helpers.config_validation as cv
|
|
|
|
from homeassistant.util.dt import utcnow
|
|
|
|
|
|
|
|
DEFAULT_NAME = "Panasonic Blu-Ray"
|
|
|
|
|
2019-05-02 12:35:22 +00:00
|
|
|
SCAN_INTERVAL = timedelta(seconds=30)
|
2018-11-21 13:22:24 +00:00
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
SUPPORT_PANASONIC_BD = (
|
|
|
|
SUPPORT_TURN_ON | SUPPORT_TURN_OFF | SUPPORT_PLAY | SUPPORT_STOP | SUPPORT_PAUSE
|
|
|
|
)
|
2018-11-21 13:22:24 +00:00
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
|
|
|
{
|
|
|
|
vol.Required(CONF_HOST): cv.string,
|
|
|
|
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
|
|
|
|
}
|
|
|
|
)
|
2018-11-21 13:22:24 +00:00
|
|
|
|
|
|
|
|
|
|
|
def setup_platform(hass, config, add_entities, discovery_info=None):
|
2019-05-02 12:35:22 +00:00
|
|
|
"""Set up the Panasonic Blu-ray platform."""
|
2018-11-21 13:22:24 +00:00
|
|
|
conf = discovery_info if discovery_info else config
|
|
|
|
|
|
|
|
# Register configured device with Home Assistant.
|
|
|
|
add_entities([PanasonicBluRay(conf[CONF_HOST], conf[CONF_NAME])])
|
|
|
|
|
|
|
|
|
2020-04-25 16:00:57 +00:00
|
|
|
class PanasonicBluRay(MediaPlayerEntity):
|
2019-05-02 12:35:22 +00:00
|
|
|
"""Representation of a Panasonic Blu-ray device."""
|
2018-11-21 13:22:24 +00:00
|
|
|
|
|
|
|
def __init__(self, ip, name):
|
2019-05-02 12:35:22 +00:00
|
|
|
"""Initialize the Panasonic Blue-ray device."""
|
2019-10-14 21:17:08 +00:00
|
|
|
self._device = PanasonicBD(ip)
|
2018-11-21 13:22:24 +00:00
|
|
|
self._name = name
|
|
|
|
self._state = STATE_OFF
|
|
|
|
self._position = 0
|
|
|
|
self._duration = 0
|
|
|
|
self._position_valid = 0
|
|
|
|
|
|
|
|
@property
|
|
|
|
def icon(self):
|
|
|
|
"""Return a disc player icon for the device."""
|
2019-07-31 19:25:30 +00:00
|
|
|
return "mdi:disc-player"
|
2018-11-21 13:22:24 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def name(self):
|
|
|
|
"""Return the display name of this device."""
|
|
|
|
return self._name
|
|
|
|
|
|
|
|
@property
|
|
|
|
def state(self):
|
|
|
|
"""Return _state variable, containing the appropriate constant."""
|
|
|
|
return self._state
|
|
|
|
|
|
|
|
@property
|
|
|
|
def supported_features(self):
|
|
|
|
"""Flag media player features that are supported."""
|
|
|
|
return SUPPORT_PANASONIC_BD
|
|
|
|
|
|
|
|
@property
|
|
|
|
def media_duration(self):
|
|
|
|
"""Duration of current playing media in seconds."""
|
|
|
|
return self._duration
|
|
|
|
|
|
|
|
@property
|
|
|
|
def media_position(self):
|
|
|
|
"""Position of current playing media in seconds."""
|
|
|
|
return self._position
|
|
|
|
|
|
|
|
@property
|
|
|
|
def media_position_updated_at(self):
|
|
|
|
"""When was the position of the current playing media valid."""
|
|
|
|
return self._position_valid
|
|
|
|
|
|
|
|
def update(self):
|
|
|
|
"""Update the internal state by querying the device."""
|
|
|
|
# This can take 5+ seconds to complete
|
|
|
|
state = self._device.get_play_status()
|
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
if state[0] == "error":
|
2019-01-24 07:20:20 +00:00
|
|
|
self._state = None
|
2019-07-31 19:25:30 +00:00
|
|
|
elif state[0] in ["off", "standby"]:
|
2018-11-21 13:22:24 +00:00
|
|
|
# We map both of these to off. If it's really off we can't
|
|
|
|
# turn it on, but from standby we can go to idle by pressing
|
|
|
|
# POWER.
|
|
|
|
self._state = STATE_OFF
|
2019-07-31 19:25:30 +00:00
|
|
|
elif state[0] in ["paused", "stopped"]:
|
2018-11-21 13:22:24 +00:00
|
|
|
self._state = STATE_IDLE
|
2019-07-31 19:25:30 +00:00
|
|
|
elif state[0] == "playing":
|
2018-11-21 13:22:24 +00:00
|
|
|
self._state = STATE_PLAYING
|
|
|
|
|
|
|
|
# Update our current media position + length
|
|
|
|
if state[1] >= 0:
|
|
|
|
self._position = state[1]
|
|
|
|
else:
|
|
|
|
self._position = 0
|
|
|
|
self._position_valid = utcnow()
|
|
|
|
self._duration = state[2]
|
|
|
|
|
|
|
|
def turn_off(self):
|
|
|
|
"""
|
|
|
|
Instruct the device to turn standby.
|
|
|
|
|
|
|
|
Sending the "POWER" button will turn the device to standby - there
|
|
|
|
is no way to turn it completely off remotely. However this works in
|
|
|
|
our favour as it means the device is still accepting commands and we
|
|
|
|
can thus turn it back on when desired.
|
|
|
|
"""
|
|
|
|
if self._state != STATE_OFF:
|
2019-07-31 19:25:30 +00:00
|
|
|
self._device.send_key("POWER")
|
2018-11-21 13:22:24 +00:00
|
|
|
|
|
|
|
self._state = STATE_OFF
|
|
|
|
|
|
|
|
def turn_on(self):
|
|
|
|
"""Wake the device back up from standby."""
|
|
|
|
if self._state == STATE_OFF:
|
2019-07-31 19:25:30 +00:00
|
|
|
self._device.send_key("POWER")
|
2018-11-21 13:22:24 +00:00
|
|
|
|
|
|
|
self._state = STATE_IDLE
|
|
|
|
|
|
|
|
def media_play(self):
|
|
|
|
"""Send play command."""
|
2019-07-31 19:25:30 +00:00
|
|
|
self._device.send_key("PLAYBACK")
|
2018-11-21 13:22:24 +00:00
|
|
|
|
|
|
|
def media_pause(self):
|
|
|
|
"""Send pause command."""
|
2019-07-31 19:25:30 +00:00
|
|
|
self._device.send_key("PAUSE")
|
2018-11-21 13:22:24 +00:00
|
|
|
|
|
|
|
def media_stop(self):
|
|
|
|
"""Send stop command."""
|
2019-07-31 19:25:30 +00:00
|
|
|
self._device.send_key("STOP")
|