Tivo 1.1 Protocol - NEW Binding Contribution!

Would you have the time to clean the code, so that we could eventually merge https://github.com/openhab/openhab2-addons/pull/684? Even if it is of no use to you anymore, it would be awesome if you could help making it available to the community this way!

@DigitalBites - thanks so much for responding and sharing your code. Completely understand the difficulty in continuing with the development without the hardware to test against.

Would you be happy if I pinged you the odd question about the code? I’ll try not to bother you too much and appreciate some time has passed since you probably last looked at this. As @Kai said, it would be such as shame to loose the work that you have done, given we were so close.

Anyway I guess I will start with a disclaimer! I’m not a Java programmer, but I have done a lot of application development in VBA / fixing others code (ok… now that you have got rid of the nasty taste in your mouth (!))… So what I am saying is that a lot of this is very new to me, so please bear with me… very much a Noob…

Having said that I’ve made a bit of progress… I’ve managed to load your code into the Eclipse IDE and I’ve managed to do enough work to address some of the compilation error messages and the error that I originally reported. So I have a working setup that is now discovering my Tivo and communicating with it :slight_smile:

There is still work to do, I still have some code I commented to compile to fix and I need to work out why I’m getting some duplicate error messages. So some more to look at here…

@Kai - my thinking was to get things basically working and free of compilation errors and then work out how to get the code into git. Do you think this is the right approach?

Anyway I wanted to let you both know where I have got to and that someone is working on this :wink:

Well, working code without compilation problems cannot be wrong, can it? :wink:

Hi all,

It’s been a steep learning curve and there may be much more that can be improved, but I think I may have a working binding for TiVo devices with many of the comments / observations addressed.

This has been tested on the latest snapshot/beta release of 2.1.0 . I am afraid I had problems on the openHAB Distribution 2.0 with the javax.jmdns not being resolved. UPDATE - see below, seems to be working OK on the release build.

Here is a link to the latest file:
org.openhab.binding.tivo_2.0.0.201701241458.jar

Rename after you have downloaded to org.openhab.binding.tivo-2.0.0-SNAPSHOT.jar and place in the add-ons directory.

In brief this release:

  • Addresses log ‘spam’ when the binding is in normal (INFO) logging mode. It is still very verbose in DEBUG mode and I may trim this down once we have confirmation things are looking good.
  • Better connection Online / Offline testing, though I suspect we may need to do more here…
  • Channel Scanning to populate the Ignore Channel List in one go.
  • Ignore channel list now supports ranges as well as in individual channel numbers
  • CHANNELUP and CHANNELDOWN operations now update the channel number after completion.

I have only one TiVO at home, so please provide some feedback especially if you have non-VirginMedia TiVo or more than one in your setup. I’ll be off to work out how to get the code into Git in the correct way and if the feedback is possitive, hopefully we can get this into the official build…

All credit to @DigitalBites for the original code.

Regards, Andy

Here is the content of the README.MD which may help if you are new to setting this up.

TiVo Binding

This binding integrates TiVo Digital Video Recorders (DVR) that support the Tivo TiVo TCP Control Protocol v1.1.

Supported Things

Most TiVo DVRs that support network remote control can be managed supported by this binding. Check the web site of your service provider for the precise specification of the TiVo box they have provided.

All TiVo devices must:

  1. be connected to a local area TCP/IP network that can be reached by the openHAB instance (this is not the WAN network interface used by cable service providers to provide the TV signal).
  2. have the Network Remote Control function enabled to support discovery and control of the device. This setting can be found using the remote control at:
  • Tivo branded boxes - Go to TiVo Central > Messages & Settings > Settings > Remote, CableCARD & Devices > Network Remote Control. Choose Enabled, press Select.
  • Virgin Media branded boxes - using the remote select Home, from the menu select, Help and Settings, Settings, Devices, Network Remote Control. Select the option Allow network based remote controls.

Binding Configuration

The binding requires no manual configuration. Tivo devices with the network remote control interface enabled, will be displayed within the Inbox.

You can also add these manually, you will need to specify the LAN IP address of your Tivo Device.

Thing Configuration

Thing file based creation has not been tested with this version.

Channels

All devices support the following channels (non exhaustive):

Channel Type ID Item Type Display Name Description
tivoChannelForce Number (1-9999) Current Channel - Forced (FORCECH) Displays the current channel number. When changed, tunes the DVR to the specified channel, cancelling any recordings in progress if necessary i.e. when all tuners are already in use / recording. The TiVo must be in Live TV mode for this command to work.
tivoChannelSet Number (1-9999) Current Channel - Request (SETCH) Displays the current channel number. When changed, tunes the DVR to the specified channel (unless a recording is in progress on all available tuners). The TiVo must be in Live TV mode for this command to work.
tivoTeleport String Change Special/Menu Screen (TELEPORT) Change to one of the following TiVo menu screens: TIVO (Home), LIVE TV, GUIDE, NOW PLAYING (My Shows).
tivoIRCommand String Remote Control Button (IRCOMMAND) Send a simulated button push from the remote control to the TiVo. See Appendix A in document TCP Remote Protocol 1.1 for supported codes.
tivoKBDCommand String Keyboard Command (KEYBOARD) Sends a code corresponding to a keyboard key press to the TiVo e.g. A-Z. See Appendix A in document TCP Remote Protocol 1.1 for supported characters and special character codes.
tivoStatus String TiVo Status Action return code / channel information returned by the TiVo.
tivoStatus String Custom Command Send any custom commands that are not documented within the official specification. Both the command and action string must be supplied. Use at your own risk, support is not provided for undocumented commands!
  • Commands to each of the channels (except ‘Custom Command’) do not need to include the command keyword only the action/parameter. So to change channel simply post/send the number of the channel without SETCH or FORCECH.
  • Custom Command is provided to allow the testing of any commands not documented within the official documentation. In this instance the COMMAND and any parameters must be sent as a single string.
  • Keyboard commands must currently be issued one character at a time to the item (this is how the natively supports these command).
  • Special characters must also be changed to the appropriate command e.g. the comma symbol( ,) must not be sent it should be replaced by ‘COMMA’.

Configuration Parameters Notes

The following notes may help to understand the correct configuration properties for your set-up:

  1. If openHAB is the only device or application that you have that makes use of the Network Remote Control functions of your Tivo, enable the Keep Connection Open option. This will connect and lock the port in-use preventing any other device from connecting it. If you use some other application, disable this option.
  2. Poll for Channel Changes only needs to be enabled if you also plan to use the TiVo remote control or other application to change channel. If openHAB is your only method of control, you can disable this option.
  3. Set the correct Minimum and Maximum channel numbers BEFORE you run a full channel scan. By default these are set at 101 and 999. Consult your Tivo program guide to find these.
  4. The Tivo will lean channel numbers that are not available as part of your subscription as you navigate / change channel. However channel changing operations will be slower if there is a large gap between valid channels. Any gap must not exceed 100. If you have a gap larger than this you must add the range of excluded channels manually or enable the Perform Channel Scan option.
  5. The Channels to Ignore section allows you to exclude any channels that you do not want to see or are not part of your subscription. Both individual channel numbers and ranges of channels are supported e.g. 109, 106, 801-850, 999.
  6. Perform Channel Scan as the name suggest will systematically change the channels between the specified Minimum and Maximum, identifying which of these are valid. At least one tuner must be available (not recording) while this operation completes. If this process is interrupted e.g. by a configuration change or restart, the system will restart the scan at the beginning. Any channels that are marked as being ignored will not be tested again.
  7. If your provider adds new channels to your subscription line-up, these will have to be manually removed from the list of Channels to Ignore. You can always remove all the entries and do a full scan again.

Hint:
You can watch a recorded item while performing a channel scan and the scan will not be impacted, provided there is at least one tuner available (not recording) throughout the process.

Full Example

####demo.items:

/* TIVO */
String      TiVo_Command_Result                             {channel="tivo:sckt:Living_Room:tivoStatus"}
String      TiVo_Fav_Channel        "Favs"                              {channel="tivo:sckt:Living_Room:tivoCommand", autoupdate="false"}
String      TiVo_ChangeScreen       "Screens"                           {channel="tivo:sckt:Living_Room:tivoTeleport", autoupdate="false"}
Number      TiVo_SetPoint           "Up/Down"                           {channel="tivo:sckt:Living_Room:tivoChannelSet"}
Number      TiVo_SetPointName       "Channel Name [MAP(tivo.map):%s]"   {channel="tivo:sckt:Living_Room:tivoChannelSet"}
String      TiVo_IRCmd              "Ir Cmd"                            {channel="tivo:sckt:Living_Room:tivoIRCommand", autoupdate="false"}
String      TiVo_KbdCmd             "Keyboard Cmd"                      {channel="tivo:sckt:Living_Room:tivoKBDCommand", autoupdate="false"}
  • The item ‘TiVo_SetPointName’ depends upon a valid tivo.map file to translate channel numbers to channel names.

####TivoDemo.sitemap:

sitemap TivoDemo label="Main Menu"
{
    Frame label="Tivo" {
        Setpoint    item=TiVo_SetPoint          label="[CH]"            icon="television"   minValue=100 maxValue=999 step=1
        Text        item=TiVo_Command_Result    label="TiVo Status"     icon="television"
        Text        item=TiVo_SetPointName      label="Channel Name"    icon="television"
        Switch      item=TiVo_Fav_Channel       label="Fav TV"          icon="television"   mappings=["SETCH 101"="BBC1", "SETCH 104"="CH 4","SETCH 110"="SKY 1",  "SETCH 135"="SyFy", "SETCH 429"="Film 4"]
        Switch      item=TiVo_Fav_Channel       label="Fav Radio"       icon="television"   mappings=["SETCH 902"="BBC R2", "SETCH 904"="BBC R4 FM", "SETCH 905"="BBC R5","SETCH 951"="Abs 80s"]
        Switch      item=TiVo_ChangeScreen                              icon="television"   mappings=["TIVO"="Home", "LIVETV"="Tv", "GUIDE"="Guide", "NOWPLAYING"="My Shows" ]
        Switch      item=TiVo_IRCmd             label="Navigation"      icon="television"   mappings=["SELECT"="Select", "EXIT"="Exit" ]
        Switch      item=TiVo_IRCmd             label="Navigation"      icon="television"   mappings=["CHANNELUP"="CH +", "CANNELDOWN"="CH -" ]
    }
}
  • Amend the minValue / maxValue to reflect the minimum and maximum channel numbers of your device.
  • This example does not use the ‘Current Channel - Forced (FORCECH)’ channel. This method will interrupt your recordings in progress when all you tuners are busy, so is obmitted for safety’s sake.
  • The item ‘TiVo_SetPointName’ depends upon a valid tivo.map file to translate channel numbers to channel names.

####tivo.map:

NULL=Unknown
100=Virgin Media Previews
101=BBC One
102=BBC Two
103=ITV
104=Channel 4
105=Channel 5

etc...

Update, I’ve just completed another rebuild with the 2.0.0 Release Build and the Tivo binding appears to be working fine.

Not sure what happened when I first tried this, but my openHabian instance crashed shortly after I tried this version, so perhaps a file had got screwed on the SD card along the way.

Bottom line, you should be able to test the binding in either the release or snapshot versions.

Regards, Andy

The following code can be used in conjunction with the HabPanel and this binding to create a Search “widget” for the TiVo platform:

The rule simply uses the appropriate commands to navigate to the integrated search pages on the TiVo. In the case of Virgin Media TiVo devices this is accessed by sending the:

  1. TIVO (Home) TELEPORT command

  2. Sending the remote control key press IRCODE number 4 (quick way to navigate TiVo menu items).

  3. Each keystroke for characters A-Z, number 0-9 and space are then sent as individual keystrokes (KEYBOARD).

The menu structure of other TiVo devices may differ, so you may need to amend the initial commands to navigate to the search page on your specific device / menu implementation.

Within the rule are a series of sleep commands Thread::sleep(300), these are added to allow the menu system to complete execution of the command before the next command is set. You may need to tweak these numbers depending on the performance of your device.

Rule code:

// Rules
rule "Search"
when
    Item TiVo_KeyboardStr received command
then
	logInfo("tivo.search","Script started ")
	if (TiVo_KeyboardStr.state != NULL && TiVo_KeyboardStr.state.toString.length > 0) {
		
		// Commands to get us to the Tivo/Home menu and select the search menu using the 'remote'
		// number keys
		sendCommand(TiVo_MenuScreen, "TIVO")
		Thread::sleep(800)
		sendCommand(TiVo_KbdCmd, "NUM4")
		Thread::sleep(800)
		
		var i = 0
		var l = 0
		var char txt = ""
		var srch = TiVo_KeyboardStr.state.toString.toUpperCase
		logInfo("tivo.search"," Searching for: " + srch)
		logDebug("tivo.search"," Search length: " + srch.length)

		while (i < (srch.length)) {
			logDebug("tivo.search"," Loop i=: " + i)
			txt = srch.charAt(i)
			logDebug("tivo.search"," txt: " + txt.toString)
			if (txt.toString.matches("[A-Z]")) {
				// Check for upper case A-Z
				sendCommand(TiVo_KbdCmd, txt.toString)
			} else if (txt.toString.matches(" ")) {
				// Check for Space
				sendCommand(TiVo_KbdCmd, "SPACE")
			} else if (txt.toString.matches("[0-9]")) {
				// Check for numbers 0-9
				l = 0
				switch txt.toString {
					case "1":
						sendCommand(TiVo_KbdCmd, "NUM1")
					case "7": {
						sendCommand(TiVo_KbdCmd, "NUM7*5")
						}
					case "9": {
						sendCommand(TiVo_KbdCmd, "NUM9*5")
						}
					default: {
						sendCommand(TiVo_KbdCmd, "NUM" + txt.toString + "*4")
						}
				}
			} else {
				logWarn("tivo.search"," Character not supported by script: " + txt)
			}
			i = i + 1
		}
	}
	lock.unlock()
end

Items:

String 		TiVo_ChangeScreen		"Screens" 			{channel="tivo:sckt:Living_Room:tivoTeleport", autoupdate="false"}
String 		TiVo_IRCmd				"Ir Cmd" 		    {channel="tivo:sckt:Living_Room:tivoIRCommand", autoupdate="false"}
String 		TiVo_KbdCmd				"Keyboard Cmd"   	{channel="tivo:sckt:Living_Room:tivoKBDCommand", autoupdate="false"}

String 		TiVo_KeyboardStr		"Search String"

HABpanel template widget HTML:

  <div class="form-group">
    <div class="col-xs-9">
       <input type="text" class="form-control" style="color: black" no-snap-drag="true" ng-model="myvalue" name="searchStr" required ng-trim="true">
    </div>
    <div class="col-xs-2">
      <button class="btn btn-primary" ng-click="sendCmd('TiVo_KeyboardStr', myvalue)">
		  Search
	   </button>
     </div>
  </div>

TESTERS WANTED!

I could really do with some feedback from other TiVo users out there…

  1. I really need confirmation that this works TiVo boxes based outside the UK i.e. non Virgin Media branded devices
  2. I need confirmation that all is OK if you have more than one TiVo device.

Thanks in anticipation!

Changes since last time:

  • Streamlined code
  • Now detects Online / Online (Standby) / Offline state of device
  • Tweaked logging to add and remove some of the logged entries.
  • Debug logging is still very verbose and is not recommended for long periods!
  • README.md is available on the GitHUB link which should help setup / understand the binding settings etc.

Latest version of the code can be downloaded from here:
org.openhab.binding.tivo_2.1.0-SNAPSHOT.jar

and viewed on GitHub here:
https://github.com/AndyXMB/openhab2-addons/tree/tivo/addons/binding/org.openhab.binding.tivo

Latest download:
org.openhab.binding.tivo_2.1.0-SNAPSHOT.jar

Changes:

  • Reduced error logging when a TiVo is offline.
  • Ability to send multiple keyboard commands by appending *n where n is the number of repeats e.g. NUM2*4 will send the number 2 keystoke 4 times.

I’ve updated the code in this post Search “widget” for the TiVo platform to use the latter enhancement.

The ability to send the same keystroke makes it possible to search for numbered items. Pressing the 2 key 4 times in rapid succession cycles through the characters A, B, C, 2, providing the desired numeric search character etc.

As always, any feedback would be great.

Regards, Andy

Latest version of my panel implementation using this binding.

The following rule code allows the translation of the channel number to channel name:

rule "MapChannel"
when
    Item TiVo_SetPoint changed
then
	var chName = ""
	chName = transform("MAP", "tivo.map", TiVo_SetPoint.state.toString)
	postUpdate(TiVo_SetPointName, chName)

end

Using a simple tivo.map file:

NULL=Unknown
100=Virgin Media Previews
101=BBC One
102=BBC Two
103=ITV

etc...

The latest code for the ‘multimedia custom template’ widget is:

<style>
	.tivobutton {width: 100%; height: 4em; border: 0; color: white; background: #424242;}
	.modgrid {padding-left: 2px; padding-right: 2px; padding-top: 2px; padding-bottom: 2px;}
	.butticon {font-size:2em;}
</style>
<div id="tivo-mediaplay"  class="table" ng-show="!showActions" ng-swipe-left="showActions = true">
	<div class="row">
		<div class="col-xs-4 modgrid">
		</div>
		<div class="col-xs-4 modgrid">
			<button class="tivobutton" ng-click="sendCmd('TiVo_IRCmd', 'PLAY')">
				<i class="glyphicon glyphicon-play butticon" alt="Play"></i>
			</button>
		</div>
		<div class="col-xs-4 modgrid">
		</div>
	</div>
	<div  class="row">
		<div class="col-xs-4 modgrid">
			<button class="tivobutton" ng-click="sendCmd('TiVo_IRCmd', 'REVERSE')">
				<i class="glyphicon glyphicon-backward butticon" alt="Backward"></i>
			</button>
		</div>
		<div class="col-xs-4 modgrid">
			<button style="background: #FFCC00; color:black" class="tivobutton" ng-click="sendCmd('TiVo_IRCmd', 'PAUSE')">
				<i class="glyphicon glyphicon-pause butticon" alt="Pause"></i>
			</button>
		</div>
		<div class="col-xs-4 modgrid">
			<button class="tivobutton" ng-click="sendCmd('TiVo_IRCmd', 'FORWARD')">
				<i class="glyphicon glyphicon-forward butticon" alt="Forward"></i>
			</button>
		</div>
	</div>
	<div  class="row">
		<div class="col-xs-4 modgrid">
		<button class="tivobutton" style="background: #666666; color:black;" ng-click="sendCmd('TiVo_IRCmd', 'REPLAY')">
				<i class="glyphicon glyphicon-step-backward butticon" alt="Step Backward"></i>
			</button>
		</div>	
		<div class="col-xs-4 modgrid">
			<button class="tivobutton" ng-click="sendCmd('TiVo_IRCmd', 'STOP')">
				<i class="glyphicon glyphicon-stop butticon" alt="Stop"></i>
			</button>
		</div>
		<div class="col-xs-4 modgrid">
			<button class="tivobutton" style="background: #666666; color:black;" ng-click="sendCmd('TiVo_IRCmd', 'ADVANCE')">
				<i class="glyphicon glyphicon-step-forward butticon" alt="Step Forward"></i>
			</button>
		</div>
	</div>
	<div  class="row" style="padding-top: 18px">
		<div class="col-xs-12">
			<button  style="width: 2em; height: 2em; border: 0; color: white; background: #0db9f0" ng-click="showActions = false">
			1
			</button>
			  
			<button style="width: 2em; height: 2em; border: 0; color: white; background: #666666" ng-click="showActions = true">
			2
			</button>
		</div>
	</div>
</div>

<div id="tivo-mediaplay"  class="table"  ng-show="showActions" ng-swipe-left="showActions = false">
	<div  class="row">
		<div class="col-xs-4 modgrid">
		</div>
		<div class="col-xs-4 modgrid">
			<button class="tivobutton" ng-click="sendCmd('TiVo_IRCmd', 'UP')">
				<i class="glyphicon glyphicon-triangle-top butticon" alt="Up"></i>
			</button>
		</div>
		<div class="col-xs-4 modgrid">
			<button class="tivobutton" style="background: #666666" ng-click="sendCmd('TiVo_IRCmd', 'CHANNELUP')">	
        Page<br>Up			
</button>
		</div>
	</div>
	<div class="row">
		<div class="col-xs-4 modgrid">
			<button class="tivobutton" ng-click="sendCmd('TiVo_IRCmd', 'LEFT')">
				<i class="glyphicon  glyphicon-triangle-left butticon" alt="Left"></i>
			</button>
		</div>
		<div class="col-xs-4 modgrid">
			<button class="tivobutton" style="background: #666666" ng-click="sendCmd('TiVo_IRCmd', 'SELECT')">
				OK
			</button>
		</div>
		<div class="col-xs-4 modgrid">
			<button class="tivobutton" ng-click="sendCmd('TiVo_IRCmd', 'RIGHT')">
				<i class="glyphicon  glyphicon-triangle-right butticon" alt="Right"></i>
			</button>
		</div>
	</div>
	<div class="row">
		<div class="col-xs-4 modgrid">
		</div>
		<div class="col-xs-4 modgrid">
			<button class="tivobutton" ng-click="sendCmd('TiVo_IRCmd', 'DOWN')">
				<i class="glyphicon  glyphicon-triangle-bottom butticon" alt="Down"></i>
			</button>
		</div>
		<div class="col-xs-4 modgrid">
			<button class="tivobutton" style="background: #666666" ng-click="sendCmd('TiVo_IRCmd', 'CHANNELDOWN')">
        Page<br>Down  			
</button>
		</div>
	</div>
		<div class="row"style="padding-top: 18px">
		<div class="col-xs-12">
			<button  style="width: 2em; height: 2em; border: 0; color: white; background: #666666" ng-click="showActions = false">
			1
			</button>
			  
			<button style="width: 2em; height: 2em; border: 0; color: white; background: #0db9f0" ng-click="showActions = true">
			2
			</button>
		</div>
	</div>
</div>

Again hope this is useful to someone out there… :slight_smile:

Andy

2 Likes

Thanks for the contribution @AndyMB. I’ve been using this binding successfully for months now. I have a Tivo Bolt bought and used within the US.

Thanks @jahubba,

LAST CALL for any user feedback on this one before I work out how to raise a PR for this binding. If you have been testing the latest .jar file and have any feedback, positive or negative NOW IS THE TIME.

Especially keen to hear from anyone out there who has more than one box working (as I only have the one).

Cheers, Andy

Andy - can you give me a couple tips on how to implement the files for your Tivo control? I’m not 100% sure what I need to install and where these go? I have Tivo working properly using sitemaps, across two Tivos.

Hi @alfista2600,

Check out this thread in the HABpanel section of the forums:

You will also find all the help you should need to get your HABpanel installation started, if you have not done this already here:
https://community.openhab.org/c/apps-services/habpanel

If you are still stuck, then please post either in this thread or the original menu / navigation one. If you can provide as much detail as possible of where you have managed to get to i.e. screenshots, what is working and what is not and copy the items that you have created for the Tivos from your items file. This makes it much easier to help etc.

Thanks for confirming you have two TiVos working with sitemaps. That is great to hear :smiley:

Regards, Andrew

Hi All,

I’ve raised the PR https://github.com/openhab/openhab2-addons/pull/2312 to promote the code. Fingers crossed I have not made any significant errors :wink:

I’m having trouble with the sign off process, so if anyone can spot what I am doing wrong, let me know.

Regards, Andy

Hi

Has anyone configured this binding manually using a .things file and if so, could you share an example.

Thanks

@Mark_Webster Mark,

See https://github.com/AndyXMB/openhab2-addons/tree/master/addons/binding/org.openhab.binding.tivo

The readme,md should hopefully answer your question. If not then let me know, so that I can improve the content. If I get this as clear as possible, should save support queries in the future etc.

Regards, Andy

Hi…

I’ve got the binding working pretty well now… Just got one question… Is it possible to configure the binding to execute the Channel Scan on a schedule to ensure the channels to ignore is kept upto date?

I’d like to be able to schedule this to execute on a monthly basis, say 3am on 1st of each month?

I’m trying to get this going with openhabian under 2.2.0 - anyone have any tips/best practices?

I’m guessing this is a dead topic since it’s been over a year since any updates, and longer since the githab repo was touched, but is anyone else using this? I’ve had it working without trouble for ages, and haven’t changed anything recently, but it has stoped working. Every attempt to change channel gives me [WARN ] [hab.binding.tivo.handler.TiVoHandler] - TiVo'tivo:sckt:316abe31' set channel command failed 'SETCH 507' with msg 'CH_FAILED NO_LIVE'
My OpenHAB is on 2.4, as nothing else was broken so I haven’t updated recently.

misha, the SETCH function only works when you’re in LIVE TV mode. From the TiVo 1.1 Protocol spec:

CH_FAILED NO_LIVE
The SETCH command failed because the UI was not in Live TV mode at the
time the command was issued