Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Samsung TV's not working [Testing fix] #20795

Closed
kdschlosser opened this issue Feb 6, 2019 · 339 comments

Comments

Projects
None yet
@kdschlosser
Copy link

commented Feb 6, 2019

*****UPDATED*****
PLEASE READ ALL THE INFORMATION BELOW THERE ARE PARTS THAT HAVE CHANGED

I am moving the conversation that is taking place in #17802 as the current conversation really has nothing to do with the issue that was reported.

If this is not OK then delete this issue. I am the person that is currently updating the code to samsungctl. It has undergone a lot of additions which I do believe the users of Home Assistant will enjoy being able to use.

thee library also now supports ALL Samsung TV's that have the capability of being controlled over a network or WiFi Connection from 2008 to present. This includes the encrypted websocket connections (H (2014) and J (2015) TV's) as well as the SSL websocket connection (latest firmware release).

I have simplified the connection process so that the only things that are needed in thee Home Assistant config file is the host (ip) of the TV. nothing else is needed. the samsungctl library now handles hammering all of the connection specific details. I also added to it a a class that handles loading and saving of config data. I did this to handle the dynamically changing tokens that are used with the encrypted websockets and SSL websockets. the library now also does not stop running if the connection get severed.. (TV gets powered off). I also changed the handling of the power keys to make them function like they should. KEY_POWER = power toggle, KEY_POWERON = power on and KEY_POWEROFF = power off.

I am currently testing the replacement for /homeassistant/components/media_player/samsungtv.py, because I am not familiar with Home Assistant it is better to hammer these problems out in an issue where they can be tested then to open a PR for non functioning code and end up with a very messy commit history.

PLEASE READ

This is a replacement for the /homeassistant/components/media_player/samsungtv.py file
please do not edit the code and then report an issue. only report problems relating to this code. also do not provide vague errors. like it says config error.. I am willing to bet the error stats more then "config error". I need a copy of the error message in it's entirety. not little bits and pieces. because of the nature of Home Assistant you may need to scroll back in the logs and read for a bit to make sure that you have grabbed all of the relevant log messages.

If you state anything about "custom_components" or if i see that in any of the errors I am not going to answer you. this is because you have modified the code. and it is a pretty good chance that your modification is what is causing the problem.

If you do not do the above then I have no way of helping to solve any issues.

config files for the TV are going to be saved in a directory called samsung_tv that is located in the Home Assistant config folder. the config files for the TVs are going to be named using the IP address you supply in the Home Assistant config yaml file.

HOME ASSISTANT CONFIG FILE
This is the only thing that needs to be added to your hass configuration.yaml file. you will not need to specify any kind of a host. or mac or name. nothing. The whole system will dynamically add TV's as it finds them (of coarse with your permission). if a TV is found you will get a notification in the hass UI. when you open this notification you will be prompted to change the display name, the mac address and the description. if you do not wish to change them simply click on the accept button. You may need to refresh the page once the device is added for it to show up. If you have more then a single TV you DO NOT need to add multiple entries into the hass config file. You only need to add the below code a single time.

If you do not want to add a TV to hass (not sure why you wouldn't) simply ignore the notification. it will disappear after 60 seconds. if you change your mind afterwards or you simply miss the timeout you will need to go into thee samsung_tv config directory and delete the file that has an extension of .noinclude.

media_player:
  - platform: samsungtv

the config file will only get saved once there is a successful connection to the TV made. I have changed about the detection mechanism for the 4 different types of connections. I am hoping this is going to be more of a dock solid mechanism of detecting the connection type. IF you have an issue detecting your TV let me know. There are some tasks I will have you do in order to get it to detect the TV properly. I do not own every Samsung TV made so there is no way to test it on my end. so it is up to you guys to follow the bug reporting directions as outline above.

Here is the updated code.

I WILL NOT MAKE CHANGES AND MAKE ANOTHER POST FOR IT. I WILL UPDATE THE CODE BELOW WITH ANY NEW CHANGES AND INFORM YOU THAT THE CODE HAS CHANGED

click to expand

"""
Support for interface with an Samsung TV.

For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/media_player.samsungtv/
"""
import asyncio
from datetime import timedelta
import logging
import threading
import os
import uuid

import voluptuous as vol

from homeassistant.components.media_player import (
    MEDIA_TYPE_CHANNEL, PLATFORM_SCHEMA, SUPPORT_NEXT_TRACK, SUPPORT_PAUSE,
    SUPPORT_PLAY, SUPPORT_PLAY_MEDIA, SUPPORT_PREVIOUS_TRACK, SUPPORT_TURN_OFF,
    SUPPORT_TURN_ON, SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_STEP,
    SUPPORT_VOLUME_SET, SUPPORT_SELECT_SOURCE, MediaPlayerDevice)
from homeassistant.const import (
    CONF_NAME,
    STATE_OFF,
    STATE_ON
)
import homeassistant.helpers.config_validation as cv
from homeassistant.util import dt as dt_util


REQUIREMENTS = [
     'https://github.com/kdschlosser/'
     'samsungctl/archive/develop.zip#samsungctl==0.8.64b'
]

SAMSUNG_CONFIG_PATH = 'samsung_tv'

ICON_TV = 'mdi:television'
ICON_TV_OFF = 'mdi:television-off'
ICON_COMPONENT = 'mdi:video-input-component'
ICON_HDMI = 'mdi:video-input-hdmi'
ICON_SVIDEO = 'mdi:video-input-svideo'
ICON_USB = 'mdi:usb'
ICON_PC = 'mdi:console'
ICON_DLNA = 'mdi:dlna'
ICON_AV = 'mdi:audio-video'
ICON_YOUTUBE = 'mdi:youtube'
ICON_HULU = 'mdi:hulu'
ICON_NETFLIX = 'mdi:netflix'
ICON_PLEX = 'mdi:plex'
ICON_SPOTIFY = 'mdi:spotify'
ICON_AMAZON = 'mdi:amazon'
ICON_PLAYSTATION = 'mdi:playstation'
ICON_UNKNOWN = 'mdi:help'

_LOGGER = logging.getLogger(__name__)

CONF_DESCRIPTION = 'description'
CONF_ADD = 'add_tv'

KEY_PRESS_TIMEOUT = 1.2
KNOWN_DEVICES_KEY = 'samsungtv_known_devices'

SUPPORT_SAMSUNGTV = (
    SUPPORT_PAUSE |
    SUPPORT_VOLUME_STEP |
    SUPPORT_VOLUME_MUTE |
    SUPPORT_PREVIOUS_TRACK |
    SUPPORT_NEXT_TRACK |
    SUPPORT_TURN_OFF |
    SUPPORT_PLAY |
    SUPPORT_PLAY_MEDIA |
    SUPPORT_VOLUME_SET |
    SUPPORT_SELECT_SOURCE
)


SAMSUNG_TV_SCHEMA = vol.Schema({
    vol.Optional(CONF_NAME): cv.string,
    vol.Optional(CONF_DESCRIPTION): cv.string,
    vol.Optional(CONF_ADD): cv.boolean,
})

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({})

_CONFIGURING = {}


def setup_platform(hass, config, add_entities, _=None):
    """Set up the Samsung TV platform."""

    config_path = hass.config.path(SAMSUNG_CONFIG_PATH)

    if not os.path.exists(config_path):
        os.mkdir(config_path)

    known_devices = hass.data.get(KNOWN_DEVICES_KEY, set())
    hass.data[KNOWN_DEVICES_KEY] = known_devices

    import samsungctl
    from samsungctl.upnp.discover import auto_discover

    config_files = list(
        os.path.join(config_path, file) for file in os.listdir(config_path)
            if file.endswith('config')
    )

    def callback(found_config):
        if found_config.uuid in known_devices:
            return

        _LOGGER.debug(str(found_config))
        known_devices.add(found_config.uuid)

        no_include = os.path.join(
            config_path,
            found_config.uuid + '.noinclude'
        )

        if os.path.exists(no_include):
            return

        if found_config.uuid not in _CONFIGURING:
            add_device(found_config, hass, config_path, add_entities)

    auto_discover.register_callback(callback)
    entities = []
    configs = []

    for config_file in config_files:
        _LOGGER.debug(config_file)
        samsung_config = samsungctl.Config.load(config_file)
        known_devices.add(samsung_config.uuid)
        configs += [samsung_config]

    auto_discover.start()

    for samsung_config in configs:
        entities += [SamsungTVDevice(samsung_config)]
    add_entities(entities)


def add_device(samsung_config, hass, config_path, add_entities):
    model = samsung_config.model
    uuid = samsung_config.uuid

    event = threading.Event()

    def samsung_configuration_callback(data):
        """Handle the entry of user PIN."""
        display_name = data.get('display_name')
        description = data.get('description')
        mac = data.get('mac')

        if display_name is None:
            display_name = samsung_config.display_name
        if description is None:
            description = samsung_config.description
        if mac is None:
            mac = samsung_config.mac

        samsung_config.display_name = display_name
        samsung_config.description = description
        samsung_config.mac = mac

        samsung_config.path = os.path.join(
            config_path,
            samsung_config.uuid + '.config'
        )

        hass.components.configurator.request_done(_CONFIGURING.pop(uuid))

        if samsung_config.method == 'encrypted':
            request_configuration(samsung_config, hass, add_entities)
        else:
            add_entities([SamsungTVDevice(samsung_config)])

        event.set()

    def do():
        event.wait(600.0)
        if not event.isSet():
            path = os.path.join(
                config_path,
                samsung_config.uuid + '.noinclude'
            )

            with open(path, 'w') as f:
                f.write('')

            hass.components.configurator.request_done(_CONFIGURING.pop(uuid))

    t = threading.Thread(target=do)
    t.daemon = True
    t.start()

    _CONFIGURING[uuid] = hass.components.configurator.request_config(
        model,
        samsung_configuration_callback,
        description='New TV discovered, would you like to add the TV?',
        description_image="/static/images/smart-tv.png",
        submit_caption="Accept",
        fields=[
            dict(
                id='display_name',
                name='Name: ' + samsung_config.display_name,
                type=''
            ),
            dict(
                id='description',
                name='Description: ' + samsung_config.description,
                type=''
            ),
            dict(
                id='mac',
                name='MAC Address : ' + str(samsung_config.mac),
                type=''
            )
        ]
    )


def request_configuration(samsung_config, hass, add_entities):
    """Request configuration steps from the user."""

    configurator = hass.components.configurator

    import samsungctl

    pin = []
    count = 0
    event = threading.Event()

    def samsung_configuration_callback(data):
        """Handle the entry of user PIN."""
        pin.append(data.get('pin'))
        event.set()

    def get_pin():
        global count

        if samsung_config.uuid in _CONFIGURING:
            count += 1
            event.clear()
            del pin[:]

            configurator.notify_errors(
                _CONFIGURING[samsung_config.uuid],
                "Failed to register, please try again."
            )
        else:
            _CONFIGURING[samsung_config.uuid] = configurator.request_config(
                samsung_config.display_name,
                samsung_configuration_callback,
                description='Enter the Pin shown on your Samsung TV.',
                description_image="/static/images/smart-tv.png",
                submit_caption="Confirm",
                fields=[{'id': 'pin', 'name': 'Enter the pin', 'type': ''}]
            )

        event.wait(60.0)

        if count == 3:
            _LOGGER.error(
                samsung_config.display_name + " TV: Pin entry failed"
            )
            return False
        elif not event.isSet():
            return None

        return pin[0]

    samsung_config.get_pin = get_pin

    def do():
        global count

        try:
            _ = samsungctl.Remote(samsung_config)
            add_entities([SamsungTVDevice(samsung_config)])
        except:
            pass

        hass.components.configurator.request_done(_CONFIGURING.pop(uuid))

    t = threading.Thread(target=do)
    t.daemon = True
    t.start()


class SamsungTVDevice(MediaPlayerDevice):
    """Representation of a Samsung TV."""

    def __init__(self, config):
        """Initialize the Samsung device."""
        from samsungctl import exceptions
        from samsungctl import Remote

        # Save a reference to the imported classes
        self._exceptions_class = exceptions
        self._remote_class = Remote
        self._config = config
        self._mac = self._config.mac
        self._uuid = self._config.uuid
        self._playing = True
        self._state = None
        self._remote = None
        self._key_source = False
        self._mute = False
        self._sources = []
        self._source = ''
        self._volume = 0.0
        self._entity_image = None
        self._tv_image = None

        if self._config.method == 'websocket':
            self._has_apps = True
        else:
            self._has_apps = False
        self._icon = ICON_TV_OFF

        self._supported_features = SUPPORT_SAMSUNGTV
        if self._config.method != 'legacy':
            self._supported_features |= SUPPORT_TURN_ON

        # Mark the end of a shutdown command (need to wait 15 seconds before
        # sending the next command to avoid turning the TV back ON).
        self._end_of_power_off = None

        # Mark the end of the TV powering on.need to wait 20 seconds before
        # sending any commands.
        self._end_of_power_on = None
        # Generate a configuration for the Samsung library

        self._remote = self._remote_class(self._config)

    def update(self):
        """Update state of device."""
        if self._power_off_in_progress():
            _LOGGER.debug(
                self._config.display_name + ' TV: Powering Off'
            )
            self._state = STATE_OFF
            self._icon = ICON_TV_OFF
            # self._entity_image = self._tv_image

        elif self._power_on_in_progress():
            _LOGGER.debug(
                self._config.display_name + ' TV: Powering On'
            )
            self._state = STATE_OFF
            self._icon = ICON_TV_OFF
            # self._entity_image = self._tv_image
        else:
            power = self._remote.power
            if power is True and self._remote.is_connected:
                self._config.save()

                if self._tv_image is None:
                    tv_image = self._remote.icon
                    if tv_image is not None:
                        self._tv_image = tv_image.data
                sources = self._remote.sources
                entity_image = self._tv_image
                source = 'Unknown'

                if sources is None:
                    if self._has_apps:
                        sources = [
                            'TV',
                            'HDMI'
                        ]

                        for app in self._remote.applications:

                            if app.is_running and app.is_visible:
                                source = 'APP: ' +app.name
                                entity_image = app.icon

                            sources += ['APP: ' + app.name]

                        self._sources = sources
                        self._source = source
                        self._entity_image = entity_image
                    else:
                        self._sources = [
                            'Source',
                            'Component 1',
                            'Component 2',
                            'AV 1',
                            'AV 2',
                            'AV 3',
                            'S Video 1',
                            'S Video 2',
                            'S Video 3',
                            'HDMI',
                            'HDMI 1',
                            'HDMI 2',
                            'HDMI 3',
                            'HDMI 4',
                            'FM-Radio',
                            'DVI',
                            'DVR',
                            'TV',
                            'Analog TV',
                            'Digital TV'
                        ]
                        self._key_source = True
                else:
                    new_sources = []
                    for src in sources:
                        if src.is_active:
                            if src.label != src.name:
                                source = src.label + ':' + src.name
                            else:
                                source = src.name

                        if src.name != src.label:
                            new_sources += [src.label + ':' + src.name]
                        else:
                            new_sources += [src.name]

                    self._key_source = False
                    self._sources = new_sources[:]

                self._source = source
                # self._entity_image = entity_image

                if self._source.upper().endswith('TV'):
                    self._icon = ICON_TV
                elif self._source.upper().endswith('USB'):
                    self._icon = ICON_USB
                elif self._source.upper().endswith('PC'):
                    self._icon = ICON_PC
                elif self._source.upper().endswith('DLNA'):
                    self._icon = ICON_DLNA

                elif 'S VIDEO' in self._source.upper():
                    self._icon = ICON_SVIDEO
                elif 'COMPONENT' in self._source.upper():
                    self._icon = ICON_COMPONENT
                elif 'AV' in self._source.upper():
                    self._icon = ICON_AV
                elif 'HDMI' in self._source.upper():
                    self._icon = ICON_HDMI
                elif 'YOUTUBE' in self._source.upper():
                    self._icon = ICON_YOUTUBE
                elif 'HULU' in self._source.upper():
                    self._icon = ICON_HULU
                elif 'NETFLIX' in self._source.upper():
                    self._icon = ICON_NETFLIX
                elif 'PLEX' in self._source.upper():
                    self._icon = ICON_PLEX
                elif 'SPOTIFY' in self._source.upper():
                    self._icon = ICON_SPOTIFY
                elif 'AMAZON' in self._source.upper():
                    self._icon = ICON_AMAZON
                elif 'PLAYSTATION' in self._source.upper():
                    self._icon = ICON_PLAYSTATION
                else:
                    self._icon = ICON_UNKNOWN

                volume = self._remote.volume
                _LOGGER.debug(
                    self._config.display_name + ' TV: Volume = ' + str(volume)
                )
                if volume is not None:
                    self._volume = volume / 100.0

                mute = self._remote.mute
                _LOGGER.debug(
                    self._config.display_name + ' TV: Mute = ' + str(mute)
                )
                if mute is None:
                    self._mute = False
                else:
                    self._mute = mute

                _LOGGER.debug(
                    self._config.display_name + ' TV: Power is On'
                )
                self._state = STATE_ON
            else:
                _LOGGER.debug(
                    self._config.display_name + ' TV: Power is Off'
                )
                # self._entity_image = self._tv_image
                self._icon = ICON_TV_OFF
                self._state = STATE_OFF

    def send_key(self, key):
        """Send a key to the tv and handles exceptions."""
        if self._power_off_in_progress():
            _LOGGER.info(
                self._config.display_name +
                " TV: powering off, not sending command: %s",
                key
            )
            return

        elif self._power_on_in_progress():
            _LOGGER.info(
                self._config.display_name +
                " TV: powering on, not sending command: %s",
                key
            )
            return

        if self._state == STATE_OFF:
            _LOGGER.info(
                self._config.display_name +
                " TV: powered off, not sending command: %s",
                key
            )
            return

        self._remote.control(key)

    @property
    def icon(self):
        """Return the icon to use in the frontend, if any."""
        return self._icon

    @property
    def entity_picture(self):
        """Return the entity picture to use in the frontend, if any."""
        return self._entity_image

    @property
    def unique_id(self) -> str:
        """Return the unique ID of the device."""
        return '{' + self._config.uuid + '}'

    @property
    def name(self):
        """Return the name of the device."""
        return self._config.display_name

    @property
    def state(self):
        """Return the state of the device."""
        return self._state

    @property
    def supported_features(self):
        """Flag media player features that are supported."""
        return self._supported_features

    def select_source(self, source):
        """Select input source."""
        if self._key_source:
            if source == 'Analog TV':
                source = 'ANTENA'

            elif source == 'Digital TV':
                source = 'DTV'

            source = source.upper().replace('-', '_').replace(' ', '')
            source = 'KEY_' + source
            _LOGGER.debug(
                self._config.display_name + ' TV: changing source to ' + source
            )
            self.send_key(source)
        else:
            if 'APP' in source:
                app_name = source.rsplit(':', 1)[-1]
                app = self._remote.get_application(app_name)

                if app is not None:
                    app.run()

            if ':' in source:
                source = source.rsplit(':', 1)[-1]
            _LOGGER.debug(
                self._config.display_name + ' TV: changing source to ' + source
            )
            self._remote.source = source

    @property
    def source(self):
        """Name of the current input source."""
        return self._source

    @property
    def source_list(self):
        """List of available input sources."""
        return self._sources

    def volume_up(self):
        """Volume up the media player."""
        self.send_key('KEY_VOLUP')

    def volume_down(self):
        """Volume down media player."""
        self.send_key('KEY_VOLDOWN')

    @property
    def volume_level(self):
        """Volume level of the media player scalar volume. 0.0-1.0."""
        return self._volume

    def set_volume_level(self, volume):
        """Set volume level, convert scalar volume. 0.0-1.0 to percent 0-100"""
        self._remote.volume = int(volume * 100)

    def mute_volume(self, mute):
        """Send mute command."""
        self._remote.mute = mute

    @property
    def is_volume_muted(self):
        """Boolean if volume is currently muted."""
        return self._mute

    def media_play_pause(self):
        """Simulate play pause media player."""
        if self._playing:
            self.media_pause()
        else:
            self.media_play()

    def media_play(self):
        """Send play command."""
        self._playing = True
        self.send_key('KEY_PLAY')

    def media_pause(self):
        """Send media pause command to media player."""
        self._playing = False
        self.send_key('KEY_PAUSE')

    def media_next_track(self):
        """Send next track command."""
        self.send_key('KEY_FF')

    def media_previous_track(self):
        """Send the previous track command."""
        self.send_key('KEY_REWIND')

    async def async_play_media(self, media_type, media_id, **kwargs):
        """Support changing a channel."""
        if media_type != MEDIA_TYPE_CHANNEL:
            _LOGGER.error(
                self._config.display_name + ' TV: Unsupported media type'
            )
            return

        # media_id should only be a channel number
        try:
            cv.positive_int(media_id)
        except vol.Invalid:
            _LOGGER.error(
                self._config.display_name +
                ' TV: Media ID must be positive integer'
            )
            return

        for digit in media_id:
            await self.hass.async_add_job(self.send_key, 'KEY_' + digit)
            await asyncio.sleep(KEY_PRESS_TIMEOUT, self.hass.loop)

    @property
    def app_id(self):
        """ID of the current running app."""
        return None

    @property
    def app_name(self):
        """Name of the current running app."""
        return None

    def turn_on(self):
        """Turn the media player on."""

        if self._power_on_in_progress():
            return

        if self._config.mac:
            self._end_of_power_on = dt_util.utcnow() + timedelta(seconds=20)

            if self._power_off_in_progress():
                self._end_of_power_on += (
                    dt_util.utcnow() - self._end_of_power_off
                )

            def do():
                _LOGGER.debug(
                    self._config.display_name + ' TV: Power on process started'
                )
                event = threading.Event()
                while self._power_off_in_progress():
                    event.wait(0.5)

                self._remote.power = True

            t = threading.Thread(target=do)
            t.daemon = True
            t.start()
        elif self._config.method != 'legacy':
            _LOGGER.info(
                self._config.display_name +
                " TV: There was a problem detecting the TV's MAC address, "
                "you will have to update the MAC address in the Home "
                "Assistant config file manually."
            )

        else:
            _LOGGER.info(
                self._config.display_name +
                " TV: Legacy TV's (2008 - 2013) do not support "
                "being powered on remotely."
            )

    def _power_on_in_progress(self):
        return (
            self._end_of_power_on is not None and
            self._end_of_power_on > dt_util.utcnow()
        )

    def turn_off(self):
        """Turn off media player."""

        if self._power_off_in_progress():
            return

        self._end_of_power_off = dt_util.utcnow() + timedelta(seconds=15)

        if self._power_on_in_progress():
            self._end_of_power_off += (
                dt_util.utcnow() - self._end_of_power_on
            )

        def do():
            _LOGGER.debug(
                self._config.display_name + ' TV: Power off process started'
            )
            event = threading.Event()
            while self._power_on_in_progress():
                event.wait(0.5)

            self._remote.power = False

        t = threading.Thread(target=do)
        t.daemon = True
        t.start()

    def _power_off_in_progress(self):
        return (
            self._end_of_power_off is not None and
            self._end_of_power_off > dt_util.utcnow()
        )

@arsaboo

This comment has been minimized.

Copy link
Contributor

commented Feb 6, 2019

There is a missing , after the line vol.Optional(CONF_METHOD): cv.string. After adding the comma, I am getting the following error:

Log Details (ERROR)
Wed Feb 06 2019 15:01:28 GMT-0500 (Eastern Standard Time)
Error while setting up platform samsungtv
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/homeassistant/helpers/entity_platform.py", line 128, in _async_setup_platform
    SLOW_SETUP_MAX_WAIT, loop=hass.loop)
  File "/usr/local/lib/python3.6/asyncio/tasks.py", line 358, in wait_for
    return fut.result()
  File "/usr/local/lib/python3.6/concurrent/futures/thread.py", line 56, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/config/custom_components/media_player/samsungtv.py", line 109, in setup_platform
    [SamsungTVDevice(host, name, description, method, uuid, config_path)]
  File "/config/custom_components/media_player/samsungtv.py", line 136, in __init__
    self._config = samsungctl.Config()
  File "/config/deps/lib/python3.6/site-packages/samsungctl/config.py", line 57, in __init__
    raise exceptions.ConfigHostError
samsungctl.exceptions.ConfigHostError: <unprintable ConfigHostError object>

My TV is UN75NU8000.

@kdschlosser

This comment has been minimized.

Copy link
Author

commented Feb 6, 2019

I updated the code in the first post to solve both problems.

@arsaboo

This comment has been minimized.

Copy link
Contributor

commented Feb 6, 2019

UPNP errors now:

Log Details (ERROR)
Wed Feb 06 2019 15:13:35 GMT-0500 (Eastern Standard Time)
Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/homeassistant/helpers/entity_platform.py", line 352, in _async_add_entity
    await entity.async_update_ha_state()
  File "/usr/local/lib/python3.6/site-packages/homeassistant/helpers/entity.py", line 239, in async_update_ha_state
    attr = self.state_attributes or {}
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/media_player/__init__.py", line 787, in state_attributes
    in ATTR_TO_PROPERTY if getattr(self, attr) is not None
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/media_player/__init__.py", line 787, in <dictcomp>
    in ATTR_TO_PROPERTY if getattr(self, attr) is not None
  File "/config/custom_components/media_player/samsungtv.py", line 302, in volume_level
    volume = self.get_remote().volume
  File "/config/deps/lib/python3.6/site-packages/samsungctl/upnp/__init__.py", line 1215, in volume
    if not self.connected:
  File "/config/deps/lib/python3.6/site-packages/samsungctl/upnp/__init__.py", line 30, in connected
    self._connect_upnp()
  File "/config/deps/lib/python3.6/site-packages/samsungctl/upnp/__init__.py", line 37, in _connect_upnp
    if not self._connected and self.power:
  File "/config/deps/lib/python3.6/site-packages/samsungctl/upnp/UPNP_Device/upnp_class.py", line 123, in __getattr__
    if item in self._devices:
  File "/config/deps/lib/python3.6/site-packages/samsungctl/upnp/UPNP_Device/upnp_class.py", line 123, in __getattr__
    if item in self._devices:
  File "/config/deps/lib/python3.6/site-packages/samsungctl/upnp/UPNP_Device/upnp_class.py", line 123, in __getattr__
    if item in self._devices:
  [Previous line repeated 322 more times]
RecursionError: maximum recursion depth exceeded

Are you on Home Assistant Discord?

@kdschlosser

This comment has been minimized.

Copy link
Author

commented Feb 6, 2019

Are you on Home Assistant Discord?

dunno what that is.

can you do me a favor. please attach this file to a post. samsungctl/upnp/__init__.py

@arsaboo

This comment has been minimized.

Copy link
Contributor

commented Feb 6, 2019

@arsaboo

This comment has been minimized.

Copy link
Contributor

commented Feb 6, 2019

Discord has Home Assistant chat server, easy to coordinate https://www.home-assistant.io/help/

Here's the Discord server link: https://discord.gg/6JJ3Rb

@kdschlosser

This comment has been minimized.

Copy link
Author

commented Feb 6, 2019

Nevermind on that last post.

I am not trying to be rude at all. but I can see you did not follow my directions.
This is the reason why I cannot stress enough to FOLLOW DIRECTIONS

it clearly states in the first post.

DO THIS FIRST

we are going to want to clean out any installed versions of the current samsungctl library. you can do this from a command prompt (shell)

pip uninstall samsungctl

I have updated some code of the code in samsungctl and the new code needs to be downloaded. and installed. I really would prefer if you also installed it from the command line using

pip install --no-cache-dir "https://github.com/kdschlosser/samsungctl/archive/develop.zip#samsungctl==0.8.0b"

this will make sure it gets installed without using a cached copy of it that may be on your system

You have an old copy of samsungctl that is being used. that is why you are getting the error.

@arsaboo

This comment has been minimized.

Copy link
Contributor

commented Feb 6, 2019

Let me reinstall Hassio afresh and test it out again. Gimme 10 min.

@arsaboo

This comment has been minimized.

Copy link
Contributor

commented Feb 6, 2019

Ok....started afresh and now I see the entity created 🎉

I have not tested anything yet. But I see the media_player entity, which is huge progress :)

@kdschlosser

This comment has been minimized.

Copy link
Author

commented Feb 6, 2019

I am going nutz over here trying to locate the problem. and i have not been able to come up with anything. I even coded up a replica of the process that is taking place and it runs fine.

you got me on this one. But it appears as tho you have has some progress. and there was possibly something latent kicking about somewhere causing the issue.

@arsaboo

This comment has been minimized.

Copy link
Contributor

commented Feb 6, 2019

I think there is definitely something wrong here. After restarting I am getting the same UPNP errors.

Log Details (ERROR)
Wed Feb 06 2019 16:58:13 GMT-0500 (Eastern Standard Time)
Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/homeassistant/helpers/entity_platform.py", line 352, in _async_add_entity
    await entity.async_update_ha_state()
  File "/usr/local/lib/python3.6/site-packages/homeassistant/helpers/entity.py", line 239, in async_update_ha_state
    attr = self.state_attributes or {}
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/media_player/__init__.py", line 787, in state_attributes
    in ATTR_TO_PROPERTY if getattr(self, attr) is not None
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/media_player/__init__.py", line 787, in <dictcomp>
    in ATTR_TO_PROPERTY if getattr(self, attr) is not None
  File "/config/custom_components/media_player/samsungtv.py", line 258, in source
    source = self.get_remote().source
  File "/config/deps/lib/python3.6/site-packages/samsungctl/upnp/__init__.py", line 950, in source
    if not self.connected:
  File "/config/deps/lib/python3.6/site-packages/samsungctl/upnp/__init__.py", line 30, in connected
    self._connect_upnp()
  File "/config/deps/lib/python3.6/site-packages/samsungctl/upnp/__init__.py", line 37, in _connect_upnp
    if not self._connected and self.power:
  File "/config/deps/lib/python3.6/site-packages/samsungctl/upnp/UPNP_Device/upnp_class.py", line 123, in __getattr__
    if item in self._devices:
  File "/config/deps/lib/python3.6/site-packages/samsungctl/upnp/UPNP_Device/upnp_class.py", line 123, in __getattr__
    if item in self._devices:
  File "/config/deps/lib/python3.6/site-packages/samsungctl/upnp/UPNP_Device/upnp_class.py", line 123, in __getattr__
    if item in self._devices:
  [Previous line repeated 322 more times]
RecursionError: maximum recursion depth exceeded

Not sure if this may be causing it, but I am using a Sonos Playbase for audio. I know it is frustrating

@kdschlosser

This comment has been minimized.

Copy link
Author

commented Feb 6, 2019

here is what I am going to do. I will bump the version on the develop branch and update the code in the first post to use the new version.

@kdschlosser

This comment has been minimized.

Copy link
Author

commented Feb 6, 2019

ok I did the version bump.

@arsaboo

This comment has been minimized.

Copy link
Contributor

commented Feb 7, 2019

So, unfortunately, the same issue, it worked after I put the code in for the first time. But after restarting HA, I get the same UPNP errors:

Log Details (ERROR)
Wed Feb 06 2019 15:47:31 GMT-0500 (Eastern Standard Time)
Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/homeassistant/helpers/entity.py", line 239, in async_update_ha_state
    attr = self.state_attributes or {}
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/media_player/__init__.py", line 787, in state_attributes
    in ATTR_TO_PROPERTY if getattr(self, attr) is not None
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/media_player/__init__.py", line 787, in <dictcomp>
    in ATTR_TO_PROPERTY if getattr(self, attr) is not None
  File "/config/custom_components/media_player/samsungtv.py", line 302, in volume_level
    volume = self.get_remote().volume
  File "/config/deps/lib/python3.6/site-packages/samsungctl/upnp/__init__.py", line 1215, in volume
    if not self.connected:
  File "/config/deps/lib/python3.6/site-packages/samsungctl/upnp/__init__.py", line 30, in connected
    self._connect_upnp()
  File "/config/deps/lib/python3.6/site-packages/samsungctl/upnp/__init__.py", line 37, in _connect_upnp
    if not self._connected and self.power:
  File "/config/deps/lib/python3.6/site-packages/samsungctl/upnp/UPNP_Device/upnp_class.py", line 123, in __getattr__
    if item in self._devices:
  File "/config/deps/lib/python3.6/site-packages/samsungctl/upnp/UPNP_Device/upnp_class.py", line 123, in __getattr__
    if item in self._devices:
  File "/config/deps/lib/python3.6/site-packages/samsungctl/upnp/UPNP_Device/upnp_class.py", line 123, in __getattr__
    if item in self._devices:
  [Previous line repeated 323 more times]
RecursionError: maximum recursion depth exceeded while calling a Python object
@arsaboo

This comment has been minimized.

Copy link
Contributor

commented Feb 7, 2019

If you are on Discord (https://discord.gg/6JJ3Rb) it will be easier to debug. I am at home and can work on it in real-time.

@kdschlosser

This comment has been minimized.

Copy link
Author

commented Feb 7, 2019

my question is what is happening when you restart.. the code that is getting loaded is changing somehow

I do not know anything about your setup. but is there a possibility of some old copy of samsungctl kicking about in some other python installations site-packags folder?.

as an example. with another project that i work on. it uses python 2.7 but it is all set up as an executable. so technically speaking there is no python installation when you install it. But. if you install python 2.7 my program will load the site-packages directory from that python installation.

Now the reason why it works right after installation is because the neew version gets plopped in the begining of the search order. once you restart the program it is no longer going to be at the beginning of that search order.

I have also run into issues because of mixes installation types. example.

if you run python setup.py install it will install the library but you get either a file or a folder name that ends with .egg but if you do the install using pip that is not the case. the wacky thing is if you install via pip after you have already installed using python setup.py install you will end up with 2 installations.. and pip gets all mucked up when removing it.

it's a strange thing.

@kdschlosser

This comment has been minimized.

Copy link
Author

commented Feb 7, 2019

I am going to add some information printouts. like the location of the library and the version.

@kdschlosser

This comment has been minimized.

Copy link
Author

commented Feb 7, 2019

OK i updated the code in the first post to give us a printout of what is going on.

@arsaboo

This comment has been minimized.

Copy link
Contributor

commented Feb 7, 2019

Here you go (had to change to error as info is not logged by default):

2019-02-07 03:14:30 ERROR (SyncWorker_7) [custom_components.media_player.samsungtv] samsungctl version: 0.8.1b
2019-02-07 03:14:30 ERROR (SyncWorker_7) [custom_components.media_player.samsungtv] samsungctl location: /config/deps/lib/python3.6/site-packages/samsungctl
2019-02-07 03:14:30 ERROR (SyncWorker_7) [custom_components.media_player.samsungtv] Samsung TV 192.168.2.252 added as 'Living Room TV'
2019-02-07 03:14:31 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/homeassistant/helpers/entity_platform.py", line 352, in _async_add_entity
    await entity.async_update_ha_state()
  File "/usr/local/lib/python3.6/site-packages/homeassistant/helpers/entity.py", line 239, in async_update_ha_state
    attr = self.state_attributes or {}
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/media_player/__init__.py", line 787, in state_attributes
    in ATTR_TO_PROPERTY if getattr(self, attr) is not None
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/media_player/__init__.py", line 787, in <dictcomp>
    in ATTR_TO_PROPERTY if getattr(self, attr) is not None
  File "/config/custom_components/media_player/samsungtv.py", line 305, in volume_level
    volume = self.get_remote().volume
  File "/config/deps/lib/python3.6/site-packages/samsungctl/upnp/__init__.py", line 1215, in volume
    if not self.connected:
  File "/config/deps/lib/python3.6/site-packages/samsungctl/upnp/__init__.py", line 30, in connected
    self._connect_upnp()
  File "/config/deps/lib/python3.6/site-packages/samsungctl/upnp/__init__.py", line 37, in _connect_upnp
    if not self._connected and self.power:
  File "/config/deps/lib/python3.6/site-packages/samsungctl/upnp/UPNP_Device/upnp_class.py", line 123, in __getattr__
    if item in self._devices:
  File "/config/deps/lib/python3.6/site-packages/samsungctl/upnp/UPNP_Device/upnp_class.py", line 123, in __getattr__
    if item in self._devices:
  File "/config/deps/lib/python3.6/site-packages/samsungctl/upnp/UPNP_Device/upnp_class.py", line 123, in __getattr__
    if item in self._devices:
  [Previous line repeated 322 more times]
RecursionError: maximum recursion depth exceeded
@arsaboo

This comment has been minimized.

Copy link
Contributor

commented Feb 7, 2019

That is the whole log - I did not modify anything. The custom_component is how you test stuff in HA when it is not officially implemented, which is the case here.

@arsaboo

This comment has been minimized.

Copy link
Contributor

commented Feb 7, 2019

What are you looking for specifically? My guess is once the entity is added, it tries to get all the properties and that is where the error appears.

Is there a way to eliminate UPNP (for now) to make sure that the basic media player works?

@kdschlosser

This comment has been minimized.

Copy link
Author

commented Feb 7, 2019

give it a try again. delete samsungctl first. I updated the code in my repository

@arsaboo

This comment has been minimized.

Copy link
Contributor

commented Feb 7, 2019

019-02-07 03:30:18 ERROR (SyncWorker_2) [custom_components.media_player.samsungtv] samsungctl version: 0.8.1b
2019-02-07 03:30:18 ERROR (SyncWorker_2) [custom_components.media_player.samsungtv] samsungctl location: /config/deps/lib/python3.6/site-packages/samsungctl
2019-02-07 03:30:18 ERROR (SyncWorker_2) [custom_components.media_player.samsungtv] Samsung TV 192.168.2.252 added as 'Living Room TV'
2019-02-07 03:30:19 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/homeassistant/helpers/entity_platform.py", line 352, in _async_add_entity
    await entity.async_update_ha_state()
  File "/usr/local/lib/python3.6/site-packages/homeassistant/helpers/entity.py", line 239, in async_update_ha_state
    attr = self.state_attributes or {}
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/media_player/__init__.py", line 787, in state_attributes
    in ATTR_TO_PROPERTY if getattr(self, attr) is not None
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/media_player/__init__.py", line 787, in <dictcomp>
    in ATTR_TO_PROPERTY if getattr(self, attr) is not None
  File "/config/custom_components/media_player/samsungtv.py", line 305, in volume_level
    volume = self.get_remote().volume
  File "/config/deps/lib/python3.6/site-packages/samsungctl/upnp/UPNP_Device/upnp_class.py", line 133, in __getattr__
    raise AttributeError(item)
AttributeError: volume
2019-02-07 03:30:30 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/homeassistant/helpers/entity.py", line 239, in async_update_ha_state
    attr = self.state_attributes or {}
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/media_player/__init__.py", line 787, in state_attributes
    in ATTR_TO_PROPERTY if getattr(self, attr) is not None
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/media_player/__init__.py", line 787, in <dictcomp>
    in ATTR_TO_PROPERTY if getattr(self, attr) is not None
  File "/config/custom_components/media_player/samsungtv.py", line 305, in volume_level
    volume = self.get_remote().volume
  File "/config/deps/lib/python3.6/site-packages/samsungctl/upnp/UPNP_Device/upnp_class.py", line 133, in __getattr__
    raise AttributeError(item)
AttributeError: volume
2019-02-07 03:30:41 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/homeassistant/helpers/entity.py", line 239, in async_update_ha_state
    attr = self.state_attributes or {}
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/media_player/__init__.py", line 787, in state_attributes
    in ATTR_TO_PROPERTY if getattr(self, attr) is not None
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/media_player/__init__.py", line 787, in <dictcomp>
    in ATTR_TO_PROPERTY if getattr(self, attr) is not None
  File "/config/custom_components/media_player/samsungtv.py", line 305, in volume_level
    volume = self.get_remote().volume
  File "/config/deps/lib/python3.6/site-packages/samsungctl/upnp/UPNP_Device/upnp_class.py", line 133, in __getattr__
    raise AttributeError(item)
AttributeError: volume
2019-02-07 03:30:52 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/homeassistant/helpers/entity.py", line 239, in async_update_ha_state
    attr = self.state_attributes or {}
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/media_player/__init__.py", line 787, in state_attributes
    in ATTR_TO_PROPERTY if getattr(self, attr) is not None
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/media_player/__init__.py", line 787, in <dictcomp>
    in ATTR_TO_PROPERTY if getattr(self, attr) is not None
  File "/config/custom_components/media_player/samsungtv.py", line 305, in volume_level
    volume = self.get_remote().volume
  File "/config/deps/lib/python3.6/site-packages/samsungctl/upnp/UPNP_Device/upnp_class.py", line 133, in __getattr__
    raise AttributeError(item)
AttributeError: volume
2019-02-07 03:31:03 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/homeassistant/helpers/entity.py", line 239, in async_update_ha_state
    attr = self.state_attributes or {}
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/media_player/__init__.py", line 787, in state_attributes
    in ATTR_TO_PROPERTY if getattr(self, attr) is not None
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/media_player/__init__.py", line 787, in <dictcomp>
    in ATTR_TO_PROPERTY if getattr(self, attr) is not None
  File "/config/custom_components/media_player/samsungtv.py", line 305, in volume_level
    volume = self.get_remote().volume
  File "/config/deps/lib/python3.6/site-packages/samsungctl/upnp/UPNP_Device/upnp_class.py", line 133, in __getattr__
    raise AttributeError(item)
AttributeError: volume
@arsaboo

This comment has been minimized.

Copy link
Contributor

commented Feb 7, 2019

Just for kicks, I removed all the volume and source related code from the component and it kinda works now. The state is still messed up, but no errors.

@kdschlosser

This comment has been minimized.

Copy link
Author

commented Feb 7, 2019

do me a favor. do not modify this one. try it first. so you ar going to have to return the changes you made back to the way they were.

I updated the develop branch of samsungctl. give it a go and see how you make out.

@arsaboo

This comment has been minimized.

Copy link
Contributor

commented Feb 7, 2019

Slightly different error this time, but still not working.

2019-02-07 13:08:30 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/homeassistant/helpers/entity_platform.py", line 352, in _async_add_entity
    await entity.async_update_ha_state()
  File "/usr/local/lib/python3.6/site-packages/homeassistant/helpers/entity.py", line 239, in async_update_ha_state
    attr = self.state_attributes or {}
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/media_player/__init__.py", line 787, in state_attributes
    in ATTR_TO_PROPERTY if getattr(self, attr) is not None
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/media_player/__init__.py", line 787, in <dictcomp>
    in ATTR_TO_PROPERTY if getattr(self, attr) is not None
  File "/config/custom_components/media_player/samsungtv.py", line 305, in volume_level
    volume = self.get_remote().volume
  File "/config/deps/lib/python3.6/site-packages/samsungctl/upnp/UPNP_Device/upnp_class.py", line 133, in __getattr__
    raise AttributeError(item)
AttributeError: volume

Wondering if there is no value for volume = self.get_remote().volume when using a soundbar/receiver. Maybe guard against that.

@ThaStealth

This comment has been minimized.

Copy link
Contributor

commented Feb 7, 2019

Okay, just a minor thing and not important for now at all, but I was setting everything up and I noticed the error below, it is just something to beautify the code:

The TV is not connected to the network (not at home now so can't investigate why it isn't), but I was doing some preparation work for later today

So I got this error (which is correct):

Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/samsungctl/remote_legacy.py", line 84, in open
    self.sock.connect((self.config.host, self.config.port))
OSError: [Errno 113] No route to host

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/src/app/homeassistant/helpers/entity_platform.py", line 352, in _async_add_entity
    await entity.async_update_ha_state()
  File "/usr/src/app/homeassistant/helpers/entity.py", line 232, in async_update_ha_state
    state = self.state
  File "/usr/src/app/homeassistant/components/media_player/samsungtv.py", line 224, in state
    power = self.get_remote().power
  File "/usr/src/app/homeassistant/components/media_player/samsungtv.py", line 178, in get_remote
    self._remote.open()
  File "/usr/local/lib/python3.6/site-packages/samsungctl/utils.py", line 24, in wrapper
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/samsungctl/remote_legacy.py", line 87, in open
    raise RuntimeError('Unable to pair with TV.. Is the TV on?!?')
RuntimeError: Unable to pair with TV.. Is the TV on?!?

But then it continues and gives this error every ~10 sec:

Update for media_player.living_room_tv fails
Traceback (most recent call last):
  File "/usr/src/app/homeassistant/helpers/entity.py", line 221, in async_update_ha_state
    await self.async_device_update()
  File "/usr/src/app/homeassistant/helpers/entity.py", line 349, in async_device_update
    await self.hass.async_add_executor_job(self.update)
  File "/usr/local/lib/python3.6/concurrent/futures/thread.py", line 56, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/src/app/homeassistant/components/media_player/samsungtv.py", line 167, in update
    power = self.get_remote().power
  File "/usr/local/lib/python3.6/site-packages/samsungctl/upnp/UPNP_Device/upnp_class.py", line 131, in __getattr__
    return self.__class__.__dict__[item].fget(self)
  File "/usr/local/lib/python3.6/site-packages/samsungctl/utils.py", line 44, in wrapper
    result = func(*args, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/samsungctl/remote_legacy.py", line 45, in power
    self.sock.self.sock.setblocking(0)
AttributeError: 'socket' object has no attribute 'self'

Perhaps you can enhance to code to check if the socket is actually open before trying to do something with it?

@arsaboo

This comment has been minimized.

Copy link
Contributor

commented Feb 7, 2019

@kdschlosser Also, see #4210 for the I/O issues. We are doing a lot of I/O inside properties, which should be avoided.

@kdschlosser kdschlosser closed this Mar 5, 2019

@Chaotic

This comment has been minimized.

Copy link

commented Mar 6, 2019

So what was the resolution to this since it was closed?

@kdschlosser

This comment has been minimized.

Copy link
Author

commented Mar 6, 2019

someone else can integrate samsungctl into hass. I do not have the time nor the want to do it.

@sermayoral

This comment has been minimized.

Copy link

commented Mar 6, 2019

@kdschlosser is the samsungctl library developer. He doesn't know the Home Assistant code. It is very annoying to understand all the code of a system that you have not developed, and he does not have to do it. We must understand that.

He also asked for help from a Home Assistant developer to help him integrate his code, but no one volunteered.

However, he continues to improve the samsungctl library to support ALL TV models, and some of us are helping him. This is the first step. Without the samsungctl library, nothing is possible in HA with Samsung TVs.

If there is a volunteer who wants to help us to debug samsungctl outside the Home Assistant environment, he just needs basic knowledge of Python, and have a TV model that tells us @kdschlosser

The first step is to complete the samsungctl library. Then we will see who can help us integrating it into Home Assistant. Some developer may see the samsungctl commit and decide to merge it in Home Assistant ...

But of course, the first thing is to complete samsungctl. Thanks for everything you are doing @kdschlosser :-)

@Answer-1

This comment has been minimized.

Copy link

commented Mar 6, 2019

I have an MU6300 if I can help you! I'd really like to have near full control of it from HA!

@arsaboo

This comment has been minimized.

Copy link
Contributor

commented Mar 6, 2019

This is exactly what I was afraid of. In trying to get everything working for ALL TVs, we are stuck with nothing working for anything. We should focus on getting the most basic component ready and then add features. I hope someone can pick this up. Thanks @kdschlosser for all your efforts.

@cjsmns

This comment has been minimized.

Copy link

commented Mar 6, 2019

This is exactly what I was afraid of.

Yep. Me too. I really hope something can come out of this. I guess it's the waiting game now.

@Onandon11

This comment has been minimized.

Copy link

commented Mar 6, 2019

This is exactly what I was afraid of. In trying to get everything working for ALL TVs, we are stuck with nothing working for anything. We should focus on getting the most basic component ready and then add features. I hope someone can pick this up. Thanks @kdschlosser for all your efforts.

Totally agree! But where are we waiting on now? The library is working as far I can see, it only has to be integrated into HA. I have extended Python knowledge and a Samsung TV, but no knowledge about HA infra. Maybe @kdschlosser can confirm the libary is working? Then we can develop the integration...

@sermayoral

This comment has been minimized.

Copy link

commented Mar 6, 2019

Thanks @Answer-1. Let's wait for @kdschlosser to tell us if he needs to test with the MU6300 model.

@Onandon11 the library is not complete. It needs to be refined with all models. Hence, we need testers

I think you are a little impatient. There are many models of Samsung TV, and ideally it would work in all.

Anyway, while @kdschlosser finishes fixing the library, you can investigate who could lead the integration in HA. I have already written a couple of emails looking for help without success.

@arsaboo I saw you have committed some code in the samsungtv component of Home Assistant. Would you be able to help in the integration with HA when samsungctl is ready?

@kdschlosser

This comment has been minimized.

Copy link
Author

commented Mar 6, 2019

ok I will tell you where I am at with the library. I need someone that uses the tuner on the TV. a TV that is 2015 or older. I am able to provide a channel lineup with channel names i simply need to know the format of the file.

if you go to this URL in your browser on your PC with the TV on and replacing YOUR_TV_IP with the IP of your TV.

http://YOUR_TV_IP:9090/BinaryBlob/3/ChannelList.dat

save the file and zip it up and attach it to an issue in the samsungctl repo.

that is the only thing left for the UPNP end of things.
The library is 100% working for legacy TV's
I did some pretty serious housekeeping on the code. and I cleaned up a lot of things and improved the overall performance of the library.
The TV discovery is 100% working now.
The power state is also working
I am in the process of getting the encrypted websocket back into running order. I removed a massive amount of code that was not needed. and removed multiple creations of the aes encryption object that gets used when connecting to the TV. I moved all of thee code that is specific to the TV control into the remote classes. you can see the large code update i did here.

kdschlosser/samsungctl@b52b2ae

I have not tested the websocket or websocket ssl portion of the library. I have not had someone that has one of these TV's offer to help in the debugging

I created a script that will test every single component of the library so helping to test only requires you to install python 2.7 and python 3.5+ install a few modules using pip in both python installations. and then run the test program. then send me the data. everything gets writen to a series of files and from those files I am able to fix issues and i can fix them really quickly.

What I had wanted to do was to add all of the available functionality of samsungctl to hass. and not just volume up and down and power. I have asked several times for guidance/help doing that portion of it and have not heard a peep from anyone. because of how hass is coded an IDE is pretty much useless in the help department. and I simply do not have the time to learn by trial and error. I do have things that require my attention other then a PC. Most of the users here are on the opposite side of the planet from me. But it seems as tho I am the one that is staying up all night working on this thing. Frankly I am getting burnt and I am falling behind with other tasks.

The library works for my TV. so anything i do now with the library is not to my benefit. it is for yours. I should not be the only one that is sacrificing in order to provide you with a way to control your TV. any of the people that have run the test program has seen the amount of data that i have to shuffle through in order to get things working. and being tired does not help.

@sermayoral

This comment has been minimized.

Copy link

commented Mar 6, 2019

And we are very grateful for your effort @kdschlosser.

Therefore, the most important thing is that you do not feel pressured. Work on the component when you have time and feel like it, and ignore all the pressures. I think nobody here does it, but sometimes it can seem like it.

There is no hurry. Currently Samsung TVs do not work properly in Home Assistant, and everything we get, however little, is an advance. We have already come a long way, and I know that eventually we will achieve it, but we have life, family, and that is the first thing. Who does not understand it, has a problem.

@kdschlosser I will try to provide you the file of the channels list you have requested. My 2014 TV should be able to provide it.

On the other hand, @Answer-1 has a MU6300 and he offered his help. I think this one uses websocket. If I'm right and you want, I can help him prepare the Python environment and get data from his TV :-)

@Answer-1

This comment has been minimized.

Copy link

commented Mar 6, 2019

@sermayoral, yep, my MU6300 uses ssl websocket. The tv was mostly working in HA before the 1250 Samsung firmware update. There was a fix to adapt the ssl websocket, which made it work again (mostly, on, off, mute, volume) but the tv got another firmware update and stopped working again.

I will gladly help if you need info from my tv. I have a PI2 laying around so I could get it running again and test what you need me to!

@sermayoral

This comment has been minimized.

Copy link

commented Mar 6, 2019

Thanks @Answer-1

Please join to slack group using this invitation: https://join.slack.com/t/samsungtvcontrol/shared_invite/enQtNTUzMDQ4ODY1MDk0LTA0Yjk3OTIwZWM0ODdmODFiMGEyNzg1OTBlZWI2YzEyYzNiMThiOTg0MDQxNDJiMjRlN2RiMDYzY2UzNjQwNTg

After that, talk to me in order to preparing your system. You need a PC connected in the same LAN than the TV. When you are ready. You only need to execute a test program and report results :-)

@Chaotic

This comment has been minimized.

Copy link

commented Mar 6, 2019

@kdschlosser thank you for the hard work you put in attempting to get this working. My last comment was just wondering what the status was.

@mlebrun

This comment has been minimized.

Copy link
Contributor

commented Mar 7, 2019

I can also try and help swap out the current implementation once it gets ready for prime time. I've at least contributed to the Samsung TV component in the past (tiny contribution of channel changing) but am willing to help out where I can, when I can! @kdschlosser I've got a websocket tv if it helps. Let me know what I can do!

@gdroos68

This comment has been minimized.

Copy link

commented Mar 15, 2019

For Athom Homey, somebody managed to make a working app. Possibly this could give some clues for the Home assistant module.

https://github.com/balmli/com.samsung.smart/tree/cd455cbb5cb27988e7e32e2489cf604e7135843d

@tmonck

This comment has been minimized.

Copy link
Contributor

commented Mar 22, 2019

@sermayoral and @kdschlosser do you guys still need testers? I have take a version of @kdschlosser library and have it running via a custom component in my home assistant so may be able to help some if desired.

@Gamelauncher

This comment has been minimized.

Copy link

commented Mar 26, 2019

@tmonck could you make a quick howto for that?

@arsaboo

This comment has been minimized.

Copy link
Contributor

commented Mar 26, 2019

@tmonck Will be great if you can share the custom component. We can then improve upon it.

@kdschlosser

This comment has been minimized.

Copy link
Author

commented Mar 27, 2019

@tmonck

I m assuming you are familiar with python. if so i could always use a hand. this is where we are testing the software at

kdschlosser/samsungctl#106. it's pretty simple. download the develop branch. and then run the RUN_ME.py file.

@tmonck

This comment has been minimized.

Copy link
Contributor

commented Mar 27, 2019

@Gamelauncher The quick howto is:

  1. Copy this directory https://github.com/home-assistant/home-assistant/tree/dev/homeassistant/components/samsungtv into your custom components directory. (This is just the default samsungtv component.
  2. Inside the media_player.py file add the following code to the init function in the SamsungTVDevice class:
       from custom_components.samsungctl import exceptions
       from custom_components.samsungctl import Remote
  1. Change 8001 to 8002 for the port
  2. Clone the samsungctl repo that is being developed by @kdschlosser.
  3. Copy that entire repo in to a samsungctl directory under custom_components directory.

@arsaboo If I had made major modifications I would share but as you can see from my steps above I am just using the existing component with no fancy addons. I am excited to attempt to help integrate some of the new features you guys have been adding.

@kdschlosser I will jump over to that issue and see where I can assist.

@arsaboo

This comment has been minimized.

Copy link
Contributor

commented Mar 27, 2019

@tmonck I see the following error

Log Details (ERROR)
Wed Mar 27 2019 18:44:12 GMT-0400 (Eastern Daylight Time)
Error while setting up platform samsungtv
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/homeassistant/helpers/entity_platform.py", line 128, in _async_setup_platform
    SLOW_SETUP_MAX_WAIT, loop=hass.loop)
  File "/usr/local/lib/python3.7/asyncio/tasks.py", line 416, in wait_for
    return fut.result()
  File "/usr/local/lib/python3.7/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/config/custom_components/samsungtv/media_player.py", line 85, in setup_platform
    add_entities([SamsungTVDevice(host, port, name, timeout, mac, uuid)])
  File "/config/custom_components/samsungtv/media_player.py", line 96, in __init__
    from custom_components.samsungctl import exceptions
  File "/config/custom_components/samsungctl/__init__.py", line 25, in <module>
    from .config import Config # NOQA
  File "/config/custom_components/samsungctl/config.py", line 8, in <module>
    from . import wake_on_lan
  File "/config/custom_components/samsungctl/wake_on_lan.py", line 17, in <module>
    from .upnp.UPNP_Device import adapter_addresses
  File "/config/custom_components/samsungctl/upnp/__init__.py", line 7, in <module>
    from .discover import discover
  File "/config/custom_components/samsungctl/upnp/discover.py", line 12, in <module>
    from ..config import Config
ImportError: cannot import name 'Config' from 'custom_components.samsungctl.config' (/config/custom_components/samsungctl/config.py)
@holdestmade

This comment has been minimized.

Copy link

commented Mar 29, 2019

Nearly working ! Mute, Volume works but power doesn't.
Also this is is my log:

Log Details (ERROR)
Fri Mar 29 2019 17:28:12 GMT+0000 (Greenwich Mean Time)
Unknown Auth Failure: 
name = HomeAssistant
description = TV
host = 192.168.1.135
port = 8002
id = ha.component.samsung
method = websocket
timeout = 1
token = None
upnp_locations = None
paired = False
mac = None
model = None
app_id = None
uuid = None
display_name = None
// ****** CEC MUST REMAIN AT THE END OF THE FILE ******
cec:
//  name = SamsungTVCEC
//  port = RPI
//  types = 4,
//  power_off = 0
//  power_standby = 0
//  wake_avr = 0
//  keypress_combo = 113
//  keypress_combo_timeout = 50
//  keypress_repeat = 200
//  keypress_release_delay = 0
//  keypress_double_tap = 100
//  hdmi_port = 1
//  avr_audio = False
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/homeassistant/components/websocket_api/commands.py", line 122, in handle_call_service
    connection.context(msg))
  File "/usr/local/lib/python3.7/site-packages/homeassistant/core.py", line 1138, in async_call
    self._execute_service(handler, service_call))
  File "/usr/local/lib/python3.7/site-packages/homeassistant/core.py", line 1160, in _execute_service
    await handler.func(service_call)
  File "/usr/local/lib/python3.7/site-packages/homeassistant/helpers/entity_component.py", line 188, in handle_service
    self._platforms.values(), func, call, service_name
  File "/usr/local/lib/python3.7/site-packages/homeassistant/helpers/service.py", line 314, in entity_service_call
    future.result()  # pop exception if have
  File "/usr/local/lib/python3.7/site-packages/homeassistant/helpers/service.py", line 328, in _handle_service_platform_call
    await getattr(entity, func)(**data)
  File "/usr/local/lib/python3.7/site-packages/homeassistant/components/media_player/__init__.py", line 734, in async_volume_down
    await self.hass.async_add_job(self.volume_down)
  File "/usr/local/lib/python3.7/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/config/custom_components/samsungtv/media_player.py", line 228, in volume_down
    self.send_key('KEY_VOLDOWN')
  File "/config/custom_components/samsungtv/media_player.py", line 156, in send_key
    self.get_remote().control(key)
  File "/config/custom_components/samsungtv/media_player.py", line 141, in get_remote
    self._remote = self._remote_class(self._config)
  File "/config/custom_components/samsungctl/remote.py", line 32, in __call__
    remote = RemoteWebsocket(config)
  File "/config/custom_components/samsungctl/utils.py", line 29, in wrapper
    return func(*args, **kwargs)
  File "/config/custom_components/samsungctl/remote_websocket.py", line 34, in __init__
    websocket_base.WebSocketBase.__init__(self, config)
  File "/config/custom_components/samsungctl/utils.py", line 29, in wrapper
    return func(*args, **kwargs)
  File "/config/custom_components/samsungctl/websocket_base.py", line 51, in __init__
    self.open()
  File "/config/custom_components/samsungctl/utils.py", line 29, in wrapper
    return func(*args, **kwargs)
  File "/config/custom_components/samsungctl/remote_websocket.py", line 213, in open
    raise RuntimeError('Unknown Auth Failure: \n' + str(self.config))
RuntimeError: Unknown Auth Failure: 
name = HomeAssistant
description = TV
host = 192.168.1.135
port = 8002
id = ha.component.samsung
method = websocket
timeout = 1
token = None
upnp_locations = None
paired = False
mac = None
model = None
app_id = None
uuid = None
display_name = None
// ****** CEC MUST REMAIN AT THE END OF THE FILE ******
cec:
//  name = SamsungTVCEC
//  port = RPI
//  types = 4,
//  power_off = 0
//  power_standby = 0
//  wake_avr = 0
//  keypress_combo = 113
//  keypress_combo_timeout = 50
//  keypress_repeat = 200
//  keypress_release_delay = 0
//  keypress_double_tap = 100
//  hdmi_port = 1
//  avr_audio = False

@romquenin

This comment has been minimized.

Copy link

commented Mar 31, 2019

   from custom_components.samsungctl import exceptions
   from custom_components.samsungctl import Remote

Thanks for sharing @tmonck, could you please point to le line where i should input this code.

Thank you.

@fillilutten

This comment has been minimized.

Copy link

commented Apr 14, 2019

   from custom_components.samsungctl import exceptions
   from custom_components.samsungctl import Remote

Thanks for sharing @tmonck, could you please point to le line where i should input this code.

Thank you.

Line 89, 90.

@dreimer1986

This comment has been minimized.

Copy link

commented Apr 30, 2019

Where did you change the port to 8002? In the copied over samsungtv code and if yes where or config?
When you say copy over the whole component of kdschlosser, you mean https://github.com/kdschlosser/samsungctl/tree/develop/samsungctl or THE WHOLE ONE?

According to the "Line 89,90" I guess we have to REPLACE the lines, right?

@Bosken85

This comment has been minimized.

Copy link

commented Jun 8, 2019

First of all, thank you for the hard work you put into this project. I am trying to run this in hass.io. everything seems to run fine except it won't discover my tv. When i look at the logs i see that the autodiscovery part only scans the known hosts from the docker container. But it never reaches the callback function defined at auto_discover.register_callback(callback). Does anybody have a working version of this on their hass.io instances? My Samsung TV is a model": "18_KANTM2_QTV", "modelName": "QE55Q6FNA", "name": "[TV] Samsung Q6 Series (55)",

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.