Control TiVo box over telnet


#142

hello mate,

does this require a specific version of ha as im gettin errors. Iv not tinkered too much, but it was complaining about plusone. I tried plusone and plus_one (as per your examples which use both btw - which is correct?)

also errors regarding missin hd channels, even when i specify one… It seems to complain about missing stuff, i add it, then it complains that iv added it!

im on 69.1 which im assuming is why im getting errors

2018-07-11 23:39:25 ERROR (MainThread) [homeassistant.config] Invalid config for [media_player.virgintivo]: expected int for dictionary value @ data[‘channels’][101][‘hd_channel’]. Got None
expected int for dictionary value @ data[‘channels’][101][‘plus_one’]. Got None. (See ?, line ?). Please check the docs at https://home-assistant.io/components/media_player.virgintivo/


#143

Yeah… I’ve been stuck on 0.64 since I’ve been running Ubuntu 16.04 which doesn’t have the correct version of Python to run later versions. Coincidentally I just upgraded to 18.04 yesterday and got the same errors once I then updated HA this morning. It seems that the config validator stuff will no longer let you default a value to “None” if you want to have it as an integer if populated.

Anyway I’ve resolved the problem and updated GitHub just now.


#144

By the way it is “plus_one” :slight_smile: . I’ll tidy up the readme.


#145

Cool thanks. Im now on the latest version of ha and just loaded your new code. noT getting the errors above now, but getting this:

2018-07-12 11:28:30 ERROR (MainThread) [homeassistant.components.media_player] Error while setting up platform virgintivo
Traceback (most recent call last):
File “/srv/homeassistant/lib/python3.5/site-packages/homeassistant/helpers/entity_platform.py”, line 129, in _async_setup_platform
SLOW_SETUP_MAX_WAIT, loop=hass.loop)
File “/usr/lib/python3.5/asyncio/tasks.py”, line 400, in wait_for
return fut.result()
File “/usr/lib/python3.5/asyncio/futures.py”, line 293, in result
raise self._exception
File “/usr/lib/python3.5/concurrent/futures/thread.py”, line 55, in run
result = self.fn(*self.args, **self.kwargs)
File “/home/homeassistant/.homeassistant/custom_components/media_player/virgintivo.py”, line 137, in setup_platform
keep_connected)
File “/home/homeassistant/.homeassistant/custom_components/media_player/virgintivo.py”, line 181, in init
self.get_guide_channels()
File “/home/homeassistant/.homeassistant/custom_components/media_player/virgintivo.py”, line 204, in get_guide_channels
hd_channel = self._channels[ch_number][CONF_HDCHANNEL]
KeyError: 106

  - platform: virgintivo
    default_is_show: false
    force_hd: true
    tivos:
      1:
        name: Virgin V6
        host: 192.168.0.10
    channels:
      100:
        name: Virgin Media Previews
      101:
        name: BBC One
        hd_channel: 108
        show: true
      102:
        name: BBC Two
        hd_channel: 162
        show: true
      103:
        name: ITV
        hd_channel: 113
        show: true
        plus_one: 114
      104:
        name: Channel 4
        hd_channel: 141
        plus_one: 142
      105:
        name: Channel 5
        hd_channel: 150
        plus_one: 155

#146

That’ll be because the example in the readme is only a partial config file - the complete one is pretty large. In the example here, only the first 5 channels are shown. When the listings are downloaded from Virgin, they contain many more channels. The first missing channel is 106 which is why that error happens.

I’ve updated the code to prevent this blowing up, but you probably want to look at the example.yaml in the code base instead. It has a full list of all the channels and you can then adjust as needed using the show attribute to pick out the channels you care about.


#147

Really good mate, youve done well here and though of most things! Im in it just for the state, which is now all working. Iv just updated all my automations aswell.

automation back to Chromecast:
  alias: Chromecast stopped - TV input / Virgin on
  trigger:
    platform: state
    entity_id: media_player.living_room_chromecast
    from: 'playing'
    to: 'off'
  action:
    - service: homeassistant.turn_on
      entity_id: switch.tv_input,media_player.sony_tv,scene.hdmi1
    - condition: template
      value_template: "{{ is_state('media_player.virgin_v6', 'off') }}"
    - service: switch.turn_on 
      entity_id: switch.virgin_power


automation switch to tv:
  alias: TV HDMI1 on - HDMI 1 Amp on
  trigger:
    platform: template
    value_template: "{{ is_state_attr('media_player.sony_tv', 'media_title', 'HDMI 1') and is_state('media_player.playstation_4', 'off') }}"
  action:
    - service: switch.turn_on
      entity_id: switch.tv_input
    - condition: state
      entity_id: media_player.virgin_v6
      state: 'off'
    - service: switch.turn_on
      entity_id: switch.virgin_power    

Im still using my telnet switches to turn it on/off - i may update them to use this at some point.

great work dude - raise a PR and get it in .74 :slight_smile:


#148

Pretty sure you can only make one telnet connection to the box at any time, so looks like I’ll have to migrate everything on to your component sooner to get it all working.


#149

Is there anyway of changing how you select a channel? My current ones are switches meanin emulated hue exposes them to alexa. Correct me if wrong, I’m not sure you can set the channel using an input select/media player using emulated hue and alexa, not without some tinkering?

Your component works fine until I use my old switches, which then takes priority over your component… I need my switches but your state functionality,but incorporated into a single component. Could you set priority of each component when the user interacts with it?


#150

On the telnet bit, yes only one thing can connect at a time. By default my component will make a permanent connection. However you can set the keep_connected attribute to false to make it disconnect after each check/command to allow it to play nicer with anything else you’ve got running.

For your other question, are you referring to the telnet switch and your “tv_lights” automation? I haven’t investigated how the telnet switch works in conjunction with this. Try setting keep_connected to false and see if that makes it play a bit nicer. I don’t know that I can have switches in the same component. I tried before and all that happened was that it created additional media_player devices with the switch names. Probably some way but currently beyond me. Let me know if it works or not and if not, I’ll try to poke it over the weekend.


#151

if changing keep_connected doesn’t work, I can’t see any reason why a template switch against my component wouldn’t work. So if you’ve still got problems, do you want to fire me over how you’ve got your switches set up and I’ll have a look? I’m probably misunderstanding your issue.


#152

Hi @Bertbert Thanks for your component but I cannot set it up and get the following errors:

 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/srv/homeassistant/lib/python3.6/site-packages/homeassistant/config_entries.py", line 345, in async_forward_entry_setup
    self.hass, component, self._hass_config)
  File "/srv/homeassistant/lib/python3.6/site-packages/homeassistant/setup.py", line 45, in async_setup_component
    return await setup_tasks[domain]
  File "/srv/homeassistant/lib/python3.6/site-packages/homeassistant/setup.py", line 56, in async_setup_component
    return await task
  File "/srv/homeassistant/lib/python3.6/site-packages/homeassistant/setup.py", line 123, in _async_setup_component
    await async_process_deps_reqs(hass, config, domain, component)
  File "/srv/homeassistant/lib/python3.6/site-packages/homeassistant/setup.py", line 233, in async_process_deps_reqs
    hass, config, name, module.DEPENDENCIES)
  File "/srv/homeassistant/lib/python3.6/site-packages/homeassistant/setup.py", line 76, in _async_process_dependencies
    results = await asyncio.gather(*tasks, loop=hass.loop)
  File "/srv/homeassistant/lib/python3.6/site-packages/homeassistant/setup.py", line 45, in async_setup_component
    return await setup_tasks[domain]
  File "/srv/homeassistant/lib/python3.6/site-packages/homeassistant/setup.py", line 56, in async_setup_component
    return await task
  File "/srv/homeassistant/lib/python3.6/site-packages/homeassistant/setup.py", line 116, in _async_setup_component
    conf_util.async_process_component_config(hass, config, domain)
  File "/srv/homeassistant/lib/python3.6/site-packages/homeassistant/config.py", line 673, in async_process_component_config
    platform = get_platform(hass, domain, p_name)
  File "/srv/homeassistant/lib/python3.6/site-packages/homeassistant/loader.py", line 58, in get_platform
    return get_component(hass, PLATFORM_FORMAT.format(domain, platform))
  File "/srv/homeassistant/lib/python3.6/site-packages/homeassistant/loader.py", line 86, in get_component
    module = importlib.import_module(path)
  File "/usr/local/lib/python3.6/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 674, in exec_module
  File "<frozen importlib._bootstrap_external>", line 781, in get_code
  File "<frozen importlib._bootstrap_external>", line 741, in source_to_code
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/home/homeassistant/.homeassistant/custom_components/media_player/virgintivo.py", line 7
    <!DOCTYPE html>
    ^
SyntaxError: invalid syntax
2018-07-13 01:18:38 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/srv/homeassistant/lib/python3.6/site-packages/homeassistant/config_entries.py", line 345, in async_forward_entry_setup
    self.hass, component, self._hass_config)
  File "/srv/homeassistant/lib/python3.6/site-packages/homeassistant/setup.py", line 45, in async_setup_component
    return await setup_tasks[domain]
  File "/srv/homeassistant/lib/python3.6/site-packages/homeassistant/setup.py", line 56, in async_setup_component
    return await task
  File "/srv/homeassistant/lib/python3.6/site-packages/homeassistant/setup.py", line 123, in _async_setup_component
    await async_process_deps_reqs(hass, config, domain, component)
  File "/srv/homeassistant/lib/python3.6/site-packages/homeassistant/setup.py", line 233, in async_process_deps_reqs
    hass, config, name, module.DEPENDENCIES)
  File "/srv/homeassistant/lib/python3.6/site-packages/homeassistant/setup.py", line 76, in _async_process_dependencies
    results = await asyncio.gather(*tasks, loop=hass.loop)
  File "/srv/homeassistant/lib/python3.6/site-packages/homeassistant/setup.py", line 45, in async_setup_component
    return await setup_tasks[domain]
  File "/srv/homeassistant/lib/python3.6/site-packages/homeassistant/setup.py", line 56, in async_setup_component
    return await task
  File "/srv/homeassistant/lib/python3.6/site-packages/homeassistant/setup.py", line 116, in _async_setup_component
    conf_util.async_process_component_config(hass, config, domain)
  File "/srv/homeassistant/lib/python3.6/site-packages/homeassistant/config.py", line 673, in async_process_component_config
    platform = get_platform(hass, domain, p_name)
  File "/srv/homeassistant/lib/python3.6/site-packages/homeassistant/loader.py", line 58, in get_platform
    return get_component(hass, PLATFORM_FORMAT.format(domain, platform))
  File "/srv/homeassistant/lib/python3.6/site-packages/homeassistant/loader.py", line 86, in get_component
    module = importlib.import_module(path)
  File "/usr/local/lib/python3.6/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 674, in exec_module
  File "<frozen importlib._bootstrap_external>", line 781, in get_code
  File "<frozen importlib._bootstrap_external>", line 741, in source_to_code
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/home/homeassistant/.homeassistant/custom_components/media_player/virgintivo.py", line 7
    <!DOCTYPE html>
    ^
SyntaxError: invalid syntax
2018-07-13 01:18:38 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/srv/homeassistant/lib/python3.6/site-packages/homeassistant/config_entries.py", line 345, in async_forward_entry_setup
    self.hass, component, self._hass_config)
  File "/srv/homeassistant/lib/python3.6/site-packages/homeassistant/setup.py", line 45, in async_setup_component
    return await setup_tasks[domain]
  File "/srv/homeassistant/lib/python3.6/site-packages/homeassistant/setup.py", line 56, in async_setup_component
    return await task
  File "/srv/homeassistant/lib/python3.6/site-packages/homeassistant/setup.py", line 123, in _async_setup_component
    await async_process_deps_reqs(hass, config, domain, component)
   File "/srv/homeassistant/lib/python3.6/site-packages/homeassistant/setup.py", line 233, in async_process_deps_reqs
    hass, config, name, module.DEPENDENCIES)
  File "/srv/homeassistant/lib/python3.6/site-packages/homeassistant/setup.py", line 76, in _async_process_dependencies
    results = await asyncio.gather(*tasks, loop=hass.loop)
  File "/srv/homeassistant/lib/python3.6/site-packages/homeassistant/setup.py", line 45, in async_setup_component
    return await setup_tasks[domain]
  File "/srv/homeassistant/lib/python3.6/site-packages/homeassistant/setup.py", line 56, in async_setup_component
    return await task
  File "/srv/homeassistant/lib/python3.6/site-packages/homeassistant/setup.py", line 116, in _async_setup_component
    conf_util.async_process_component_config(hass, config, domain)
  File "/srv/homeassistant/lib/python3.6/site-packages/homeassistant/config.py", line 673, in async_process_component_config
    platform = get_platform(hass, domain, p_name)
  File "/srv/homeassistant/lib/python3.6/site-packages/homeassistant/loader.py", line 58, in get_platform
    return get_component(hass, PLATFORM_FORMAT.format(domain, platform))
  File "/srv/homeassistant/lib/python3.6/site-packages/homeassistant/loader.py", line 86, in get_component
    module = importlib.import_module(path)
  File "/usr/local/lib/python3.6/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 674, in exec_module
  File "<frozen importlib._bootstrap_external>", line 781, in get_code
  File "<frozen importlib._bootstrap_external>", line 741, in source_to_code
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/home/homeassistant/.homeassistant/custom_components/media_player/virgintivo.py", line 7
    <!DOCTYPE html>
    ^

#153

I think you might have downloaded the HTML of the page rather than the component. The giveaway is the bit:

File “/home/homeassistant/.homeassistant/custom_components/media_player/virgintivo.py”, line 7

If I view the HTML of the page I can see that line 7 is indeed that. However if you go to the raw version of the page at:

https://raw.githubusercontent.com/bertbert72/HomeAssistant_VirginTivo/master/virgintivo.py

You’ll see the actual code. Usually it’s easier just to download the repository and grab the file, but the above link will take you to it as well.


#154

thank you that was it ! will play around with the component now.


#155

Ah yeah i could do a template switch on your component i guess, means i have to re-write some of my stuff though - any excuse !

Heres one of my switches:

switch channel_28:
  platform: telnet
  assumed_state: True
  switches:
    e4_virgin:
     resource: '192.168.0.10'
     port: 31339
     command_on: 'SETCH 106'
     command_off: 'SETCH 106'
     name: E4 

Just trying the keep connected attribute now to see how that helps.

Cheers mate


#156

boom -i can use both now. Thanks for your help mate


#157

Great :slight_smile: Thought that might come in useful.


#158

My other virgin switches are very slow now :cry:

Edit : Just commented out the guide and scan interval and all appears well now


#159

I don’t think the guide should really have any effect since it loads at start up and then updates every 12 hours or so. The socket timeout is 1 second so I suppose there is a chance that it could sit for that second waiting for a timeout and then immediately run again (assuming that’s how it all works which I’m not sure of), so I was going to suggest changing the scan_interval to 2. The default scan_interval is 10 seconds - if you’re happy enough with that resolution, it should be fine to comment out.

Or I could reduce down the socket timeout to say 0.3 seconds.


#160

To be slightly more accurate, the guide loads per channel when it is first switched to the channel and covers the next 12 hours of programs. It then won’t update again until the last program is finished. It can take a second or two to retrieve the listings. There might be a problem there though. The socket could be blocked while it does that - no reason that it should be. I’ll make a quick change…


#161

Ok, if you can be bothered re-enabling the guide and scan_interval, give that a go. It’ll now free the telnet connection before updating the guide.