Sample Pages

Here's a list of sample pages. These sample pages normally contain enough information so you can test them at your site. The samples illustrate or highlight an individual aspect of the MyURemote solution, and are of little use in practice. But they do explain the basics, and you can return to them when building your own site.

List of samples

Introduction

The samples are available here.

Every sample page has a html structure like this :

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
		<meta name="viewport" content="width=device-width, height=device-height, user-scalable=no" />
	 	<title>Sample 1</title>
 
		<link href="style/samples.css" rel="stylesheet" type="text/css" />
 
		<script src="js/jquery-1.7.2.js"></script>
		<script src="js/jquery.jsonp-2.1.2.js"></script>
 
		<!--  	Client-independent files
			Contain classes for communication with the MyURemote app 
		-->
		<script src="js/myuremote.js"></script>
		<script src="js/..."></script>
 
		<!-- Sample functions -->
		<script type="text/javascript">
			sample javascript
		</script>
 
	</head>
 
 	<body>
		Sample html
	</body>
</html>

Important elements are

  • the javascript imports js/jquery-1.7.2.js and js/jquery.jsonp-2.1.2.js. This loads the jquery Javascript library and the jquery-json plugin.
  • the javascript imports js/myuremote.js and optionally implementation classes for other extenders.
  • javascript functions specific to this sample
  • the html body

We have chosen jquery as the base of our Javascript. We may develop another library for dojo as well, but there are no concrete plans to do so.

You can download the javascript files here

The javascript files presented here (myuremote.js, gc.js, …) are also available from verdegem.com/domotics. However, I think my versions are better ;-)

You can check for yourself.

Sample 1

The sample page is available at ../sample01.html.

This sample shows how to send infrared signals to a device, using a Global Caché extender.

For this sample, we need to import the extender implementation class for the Global Caché extender.

<script src="js/gc.js"></script>

The sample javascript is rather simple

<script type="text/javascript">
	var gatewayUrl = "http://localhost:9090/myuremote";
 
	function executeCommand(id) {
		// get the Global Caché ip address from the gcip input field
		var ip 		= $("#gcip").val();
		// get the Global Caché port from the gcport input field
		var port 	= $("#gcport").val();
		// get the Global Caché module from the gcmodule input field
		var module 	= $("#gcirmodule").val();
		// get the command string from the input field with the given id
		var command	= $("#" + id).val();
 
		var extenderParams = {};
		ip && (extenderParams.ip = ip);
		(port > 0) && (extenderParams.port = port);
 
		var gcextender = new gc(extenderParams);
 
		gcextender.executeCommand({
			module : module,
			commandString : command,
			callbackSuccess: 	function(response) {
							alert(response.result);
						},
			callbackError : 	function(error) {
							alert(error);
						}
		});
	};
</script>

First, the gateway url must be defined. This is the base url of the local http server.

Second, we define the function executeCommand gets all necessary parameters to send a command to the Global Caché extender. This is done using the jquery construction

$("#id").val();

$(”#id”) gives us the input element with id “id” (the # in front of the id signifies we want to look for an id). The val() function returns the value of the input element.

With these parameters, we create a parameter object extenderParams, which is used to create the a extender instance

var gcextender = new gc(extenderParams);

The extender instance is created with the given ip address and port.

Finally, we fire the method executeCommand. The method executeCommand of the Global Caché extender instance requires the following parameters

  • module : the module through which to send the command
  • commandString : the full command to send to this module
  • callbackSuccess and callbackError : callback functions to be executed when the Global Caché extender returns a response.

Bottom line : to send an ir command, you need to create an instance of the gc extender, and execute a command with at least

gcextender.executeCommand({
	module : "ir3",
	commandString : "1,37000,1,1,12,11,12,22,12,11,24,22,12,11,24,22,24,22,12,11,24,22,24,10,12,22,24,740"
});

Sample 2

This sample page is available at ../sample02.html.

This sample treats how to use serial commands for a Global Caché extender.

There are some issues with serial commands.

  1. Serial commands are sent to a different port than ir commands. By default, the port for sending ir commands is 4998. The first serial module is available at 4999, and the second serial module at 5000. In general, if you have modified the base port (for the ir commands), the first serial module is available at <ir port> + 1, the second at <ir port> + 2.
  2. If the serial commands is in hexadecimal format, such as '\x0B\x00\x01\x04\xA0\x01\x64\x00\x00\x00\xCB', and the string is taken from an input field, the string needs to be converted before it is sent to the local http server. This is because there is a mismatch between the web page's Utf-8 encoding and the Latin-1 encoding that is required by the Global Caché extender.

For commands that are defined in a javascript file, this conversion is not needed.

There is a jquery plugin in the myuremote.js file that takes care of the conversion. Simply use the function convertHex() on a jquery input to make this work, for example

$(<selector>).convertHex()[0];

The function convertHex() can be executed on an array of elements (as returned by $(<selector>). Even if only a single element is returned, the function will return an array with one element.

In this sample, we also need to import the gc.js javascript file.

<script src="js/gc.js"></script>

In the sample, a few javascript functions are defined :

getExtender : reads the ip, base port and module and returns a new extender instance. This function uses the jquery construct $(”#” + id).val() to get the value from an input field with a given id. If the ip and/or port are left empty, then the default port as defined in the MyURemote app will be used.

function getExtender() {
	// get the Global Caché ip address from the gcip input field
	var ip 		= $("#gcip").val();
	// get the Global Caché port from the gcport input field
	var port 	= $("#gcport").val();
 
	var extenderParams = {};
	ip && (extenderParams.ip = ip);
	(port > 0) && (extenderParams.port = port);
	var gcextender = new gc(extenderParams);
 
	return gcextender;
}		

setVolume and getVolume : functions that set or read a value. Note that the module is obtained from the radio button using the construct $(“input[name=gcsermodule]:checked”).val()

function setVolume() {
	var gcextender = getExtender();
 
	gcextender.executeCommand({
		module : $("input[name=gcsermodule]:checked").val(),
		commandString : "VS " + parseInt($("#boseVolume").val()).toString(16),
		callbackSuccess: 	function(response) {
						parseVolume(response, "boseVolumeOutput");
					}
	});
};
 
function getVolume() {
	var gcextender = getExtender();
 
	gcextender.executeCommand({
		module : $("input[name=gcsermodule]:checked").val(),
		commandString : "VG ",
		callbackSuccess: 	function(response) {
						parseVolume(response, "boseVolumeOutput");
		}
	});
};

executeCommand : this function actually sends a serial command to the Global Caché extender, via the MyURemote app. The input can be either the id of an input field, or a commandString itself. The first lines test whether the input is from an id (with a try-catch clause in case jquery fails on special characters in the input).

Once the module and the commandString are deduced, the command is sent exactly like for an infrared signal. The response is handled by a function printResponse.

function executeCommand(input) {
	var gcextender = getExtender();
 
	try {
		var inputField = $("#" + input);
		if (inputField) {
			commandString = $("#" + input).convertHex()[0];
		} else {
			commandString = input;
		}		
	} catch (e) {
		commandString = input;
	}
 
	gcextender.executeCommand({
		module : $("input[name=gcsermodule]:checked").val(),
		commandString : commandString,
		callbackSuccess: 	function(response) {
						printResponse(response, "gcseroutput");
					}
	});
};

The function parseVolume simply parses a number from a string. This is nothing special, but we just give it as reference.

function parseVolume(response, outputTextField) {
	var volume = response.result.match(/\d/g);
	volume = volume.join("");
	$("#" + outputTextField).val(volume);
};

Sample 3

The previous samples used the executeCommand of the gc class, which contains the logic to differentiate between infrared and serial signals, checks the ports, …

If you want full control over your commands, you can also use the executeRaw command. The only parameters you need are

  • ip
  • port
  • command

In this case, if you want to send a command to a serial port, you need to explicitly specify the correct port.

The sample is available at ../sample03.html.

In this sample, we also need to import the gc.js javascript file.

<script src="js/gc.js"></script>

We define the same getExtender function as in Sample 2.

function getExtender() {
	// get the Global Caché ip address from the gcip input field
	var ip 		= $("#gcip").val();
	// get the Global Caché port from the gcport input field
	var port 	= $("#gcport").val();
	// get the Global Caché module from the gcmodule input field
 
	var extenderParams = {};
	ip && (extenderParams.ip = ip);
	(port > 0) && (extenderParams.port = port);
 
	var gcextender = new gc(extenderParams);
 
	return gcextender;
}

And one additional function

function executeRaw(input) {
	var gcextender = getExtender();
 
	gcextender.executeRaw($("#" + input).convertHex()[0] + "\r");
};

This executeRaw function reads the value, optionally converts a hexadecimal string, adds a carriage return, and calls the function executeRaw from the gc extender instance.

With the executeRaw function, you are responsible for ip address, port, converting hexadecimal values, and adding the required carriage return.

For ir commands, be sure to add sendir in front of the command, followed by the module in the format 4:1 (ir1), 4:2 (ir2), 4:3 (ir3), 5:1 (ir4), 5:2 (ir5), 5:3 (ir6).

For serial commands, nothing has to be added except the carriage return and the hexadecimal character convertion if using an input field.

Sample 4

REST is an approach that leverages the HTTP protocol, and is not an alternative to it.

You can test a HTTP GET command in a webbrowser: fi: direcTV sat receiver UP command: http://192.168.1.20:8080/remote/processKey?key=up

in MyURemote is this:

"DirecTV":{

"ip":{

"methods":{

"processGet":{"type":"GET", "path": "/remote/processKey", "parameters" : ["key"] }

},

"UP":{

"method":"processGet",

"parameters":["up"]

}

In this sample, we use a rest protocol to communicate with a Philips TV. The TV supports version 2k11 of the rest protocol for the JointSpace architecture.

The sample is available at ../sample04.html.

In this sample, we also need to import the rest.js javascript file.

<script src="js/rest.js"></script>

As in the previous samples, we define the same getExtender function, which will now create a instance of the rest class. This extender needs an ip address and a port, which is fixed at 1925.

function getExtender() {
	// get the Philips Tv ip address from the tvip input field
	var ip 		= $("#tvip").val();
	// get the Philips Tv port from the tvport input field
	var port 	= $("#tvport").val();
 
	var extenderParams = {};
	ip && (extenderParams.ip = ip);
	(port > 0) && (extenderParams.port = port);
 
	var restExtender = new rest(extenderParams);
 
	return restExtender;
}

The function executeRestCommand is used to send a key command to the Philips TV.

To execute a key command, send a http POST request to the url

http://<ip address>:1925/1/input/key

with the following json object in the body

{
    "key": "<the key to press>"
}

The rest protocol is documented at http://jointspace.sourceforge.net/projectdata/documentation/jasonApi/1/doc/API.html. Specific documentation for the key command can be found at http://jointspace.sourceforge.net/projectdata/documentation/jasonApi/1/doc/API-Method-input-key-POST.html

function executeRestCommand(key) {
	var restExtender = getExtender();
 
	restExtender.executeCommand({
		commandString : "/1/input/key",
		commandParams : {
			"key" : key
		},
		type : "POST"
	});
};

Sample 5

This sample page is available at ../sample05.html.

This sample treats how to use the serial output of a Global Caché extender to control a Bose multi-room system.

The demo is only suitable for Bose Lifestyle systems (V20, V30, 28, 38, 48). For more recent versions, there is another working implementation, however this is not documented here.

For the serial communication, we need to be aware of the following issue.

  1. Serial commands are sent to a different port than ir commands. By default, the port for sending ir commands is 4998. The first serial module is available at 4999, and the second serial module at 5000. In general, if you have modified the base port (for the ir commands), the first serial module is available at <ir port> + 1, the second at <ir port> + 2.
  2. When using the gc javascript class, the port is taken care of automatically. You only have to specify the port of the ir module.

</note>

In this sample, we need to import the gc.js javascript file.

<script src="js/gc.js"></script>

A few javascript functions are defined :

getExtender : reads the ip, base port and module and returns a new extender instance. This function uses the jquery construct $(”#” + id).val() to get the value from an input field with a given id. If the ip and/or port are left empty, then the default port as defined in the MyURemote app will be used.

function getExtender() {
	// get the Global Caché ip address from the gcip input field
	var ip 		= $("#gcip").val();
	// get the Global Caché port from the gcport input field
	var port 	= $("#gcport").val();
 
	var extenderParams = {};
	ip && (extenderParams.ip = ip);
	(port > 0) && (extenderParams.port = port);
	var gcextender = new gc(extenderParams);
 
	return gcextender;
}		

executeBoseCommand : this function actually sends a serial command to the Global Caché extender, via the MyURemote app. The command string is prepared in this function.

A command is built up as follows :

KP <key code>,,,,<zone>,<room>

  • <key code> is defined by the value of the selected command option of the drop down box
<select id="boseKey">
	<option value="01">ONOFF</option>
	<option value="44">ON</option>
	<option value="46">OFF</option>
	<option value="2E">ALLOFF</option>
	<option value="35">MUTE</option>
	<option value="02">MUTEALL</option>
	<option value="1A">VOL+</option>
	<option value="1B">VOL-</option>
	...
</select>
  • <zone> can be either 0 (zone A) or 1 (zone B). This is defined by the value of the selected zone option
<select id="boseZone">
	<option value="0">Zone A</option>
	<option value="1">Zone B</option>
</select>
  • <room> is a number between 0 and 13. This is defined by the value of the selected room option
<select id="boseRoom">
	<option value="0">Room 0</option>
	<option value="1">Room 1</option>
	...
</select>

Once the module and the commandString are deduced, the command is sent exactly like for an infrared signal. The response is handled by a function printResponse.

function executeBoseCommand() {
	var gcextender = getExtender();
 
	// get key, zone and room from the select boxes
	var key 	= $("#boseKey").val();
	var zone 	= $("#boseZone").val();
	var room 	= $("#boseRoom").val();
 
	// build the command string 
	var commandString = "KP " + key + ",,,," + zone + "," + room;
 
	// send the command string to the Global Caché (via the MyURemote local http server)
	gcextender.executeCommand({
					module : $("input[name=gcsermodule]:checked").val(),
					commandString : commandString,
					callbackSuccess: 	function(response) {
											printResponse(response, "gcseroutput");
										}
				});
	};
}

The function printResponse simply prints the response in a below the input fields.

function printResponse(response, outputTextField) {
	$("#" + outputTextField).text(response.result);
}

Sample 6

This sample introduces the own protocol to communicate with a bTicino MyHome system through the OpenWebNet protocol.

The sample is available at ../sample06.html. We need to import the own.js javascript file.

<script src="js/own.js"></script>

As in the previous samples, we define the same getExtender function, which will now create a instance of the own class. This extender needs an ip address and a port, which is fixed at 20000.

function getExtender() {
	// get the OWN Server ip address from the ownip input field
	var ip 		= $("#ownip").val();
	// get the OWN Server port from the ownport input field
	var port 	= $("#ownport").val();
 
	var extenderParams = {};
	ip && (extenderParams.ip = ip);
	(port > 0) && (extenderParams.port = port);
 
	var ownExtender = new own(extenderParams);
 
	return ownExtender;
}

Currently only lights and shutters are supported, but it shouldn't be too hard to add other component types.

The protocol is documented at Wikipedia.

You need an OWN server (gateway) in your network, e.g. a MH200 device. For a full list of OWN gateways, see http://www.myopen-legrandgroup.com/devices/gateways/default.aspx.

To execute a command, the command needs to be sent over a socket connection to the given own ip address at port 20000.

A command looks like

*WHO*WHAT*WHERE##
  • WHO specifies the type of component, e.g. 1 for Lights, 2 for Shutters, …
  • WHAT specifies the target status, e.g. 0 for Light Off, 1 for Light On, and other values for shutters and other component types
  • WHERE is the address of the light or the shutter on the local bus. The address can vary from 0 to 99.

In the sample, there is a section to control lights, and a section to control shutters. In the Lights section, you can enter the address of a light, and then click the On or Off button. In the Shutters section, you can enter the address of the shutter, and then click the Up, Stop or Down buttons.

The function executeOWNCommand is used to send a command to the MyHome system. Depending on the type (light or shutter), the address is read from the correct input field.

Once the commandString is built up, it is displayed in a text field below the buttons, and then it is sent to the MyHome system via the MyURemote application.

function executeOWNCommand(type,action) {
	var ownExtender = getExtender();
 
	var address = $("#" + type).val();
	var actionString = "*" + typeInfo[type] + "*" + actionInfo[type][action] + "*" + address;
 
	$("#" + type + "_command").val(actionString);
	ownExtender.executeCommand({
		commandString : actionString
	});
};

Sample 7

In this sample, we use a rest protocol to communicate with a Panasonic Blu-Ray player. The Panasonic device supports an undocumented protocol. Information about the protocol is derived from http://www.perceptiveautomation.com/userforum/viewtopic.php?t=6810&p=41085.

The sample is available at ../sample07.html.

In this sample, we also need to import the rest.js javascript file.

<script src="js/rest.js"></script>

As in the previous samples, we define the same getExtender function, which will now create a instance of the own class. This extender needs an ip address and a port, which is fixed at 1925.

function getExtender() {
	// get the Panasonic ip address from the psip input field
	var ip 		= $("#psip").val();
	// get the Panasonic port from the psport input field
	var port 	= $("#psport").val();
 
	var extenderParams = {};
	ip && (extenderParams.ip = ip);
	(port > 0) && (extenderParams.port = port);
 
	var restExtender = new rest(extenderParams);
 
	return restExtender;
}

The function executeRestCommand is used to send a command to the Panasonic device.

To execute a key command, send a http POST request to the url

http://<ip address>:80/WAN/dvdr/dvdr_ctrl.cgi

with the following data in the body

cCMD_RC_<command>.x=100&cCMD_RC_<command>.y=100

where <command> is a string such as

  • POWER (Power)
  • OP_CL (Open/Close)
  • D1 (Key 1)
  • …

The Panasonic protocol makes use of the User-Agent header. This header must be set to MEI-LAN-REMOTE-CALL.

This is ok for a smartphone using a WebView component. The MyURemote app correctly sets this User-Agent for all http calls from within the view component. It does this for non-Panasonic related calls as well, but other protocols do not really care about the User-Agent header.

If you want to test this sample on Windows, e.g. using Internet Explorer or Firefox, you must set the User-Agent your self, as this cannot be altered by javascript code.

In the demo, all commands are represented by a button. The command string is defined as the value of the input element.

We need some additional variables to configure the allowed values of type and action.

var gatewayUrl = "http://localhost:9090/myuremote";
var typeInfo = {
	"light":"1",
	"shutter":"2"
}

var actionInfo = {
	"light":{
		"on":"1",
		"off":"0"
	},
	"shutter":{
		"up":"1",
		"down":"2",
		"stop":"0"
	}
}

The function executeRestCommand reads this value, and builds the post data from it. It does this by defining a command TEMPLATE, and by using a Regular expression to replace the {0} elements with the command string.

The command is sent to the url built from the extender ip and port, and the PATH variable.

var TEMPLATE 	= "cCMD_RC_{0}.x=100&cCMD_RC_{0}.y=100";
var PATH	= "/WAN/dvdr/dvdr_ctrl.cgi";
 
function executeRestCommand(button) {
	var key 		= button.value;
	var restExtender 	= getExtender();
 
	// use the template to create the POST data
	var pattern 	= "\\{0\\}";
	var regexp 	= new RegExp(pattern, "g");
	var postData 	= TEMPLATE.replace(regexp, key);
 
	var url = "http://" + restExtender.extender.ip + ":" + restExtender.extender.port + PATH;
	restExtender.executeCommand({
		url 		: url,
		type 		: "POST",
		postData 	: postData
	});
};

Sample 8

In this sample, we use a specific, undocumented Samsung protocol to communicate with a Samsung SmartTV. Information about the protocol is derived from http://deneb.homedns.org/things/?p=232 or https://gist.github.com/998441.

The sample is available at ../sample08.html.

The commands are encoded using a Base64 encoding algorithm. We need to import the correct jquery library.

<script src="js/jquery.base64.min.js"></script>

In this sample, we need to import the samsung.js javascript file.

<script src="js/samsung.js"></script>

In order to communicate with a Samsung SmartTV, we need to communicate with the gateway, so we need the gateway url. We also need to pass our ip address and mac address (as part of the Samsung protocol). The MyURemote app offers a url where you can get this network information. We therefore need the variables

var gatewayUrl 	= "http://localhost:9090/myuremote";
var infoUrl		= "http://localhost:9090/getinfo";

And an extra call to the MyURemote app is necessary to get the network information. The samsung.js file requires the existence of a netInfo variable.

var netInfo;
 
function getNetInfo() {
	$.jsonp({
		url					: infoUrl,
		callbackParameter 	: "callback", 
		async : false,
	    success: function(response) {
			netInfo = response;
 
			$.myuremote.log("debug", "retrieved network info ");
			$.myuremote.log("debug", "  ip " + netInfo.ip);
			$.myuremote.log("debug", "  mac " + netInfo.mac);
	    },
	    error: function(type, error) {
	    	$.myuremote.log("error", "failed to retrieve network info ");
	    }
	});
}
 
getNetInfo();

As in the previous samples, we define the same getExtender function, which will now create a instance of the own class. This extender needs an ip address and a port, which is fixed at 55000.

function getExtender() {
	// get the Samsung ip address from the psip input field
	var ip 		= $("#samsungip").val();
	// get the Samsung port from the psport input field
	var port 	= $("#samsungport").val();
 
	var extenderParams = {};
	ip && (extenderParams.ip = ip);
	(port > 0) && (extenderParams.port = port);
 
	var samsungExtender = new samsung(extenderParams);
 
	return samsungExtender;
}

The function executeSamsungCommand is used to send a command to the Samsung SmartTV. A command is a string like

  • KEY_POWER
  • KEY_MENU
  • KEY_1
  • …

Sending a command is simple enough. The function executeSamsungCommand gets the value from the input element (button), and passes it to a samsungExtender instance.

function executeSamsungCommand(button) {
	var key 		= button.value;
	var samsungExtender 	= getExtender();
 
	// send the key
	samsungExtender.executeCommand({
		commandString : key
	});
};

Only for your information : the difficulty with the Samsung protocol lies in the fact that it's a 2-way protocol. First, an initialization string is sent, and when successfully received, the actual key command is sent. The socket needs to remain open inbetween (in all other situations, a new socket connection is created for every action). This is achieved by adding the query parameter keepOpen to the http request.

Furthermore, creating the command strings is a little awkward. However, the samsung object takes care of all this.

Sample 9

Using Contexts and Client configurations This sample shows how to use a client configuration and contexts, to make your application more generic.

This sample page is available at ../sample09.html.

Sample 10

LG Smart TV (post communication)

This sample page is available at ../sample10.html.

Sample 11

Pioneer Receiver (socket communication)

This sample page is available at ../sample11.html.

Sample 12

Sony BluRay

This sample page is available at ../sample12.html.

Sample 13

Bose Soundtouch

This sample page is available at ../sample13.html.

Sample 14

Western Digital Live

This sample page is available at ../sample14.html.

Sample 15

Yamaha YNC1

This sample page is available at ../sample15.html.

Sample 16

Yamaha YNC2

This sample page is available at ../sample16.html.

Sample 17

Yamaha YNC

This sample page is available at ../sample17.html.

Sample 18

Discovery

This sample page is available at ../sample18.html.

Sample 19

IRDA (most basic remote for android built-in IR blaster)

these files are needed!!!

src="js/jquery-1.7.2.js"

src="js/jquery.jsonp-2.1.2.js"

src="js/jquery.class.js"

src="js/myuremote.js"

src="js/extender.js"

src="js/irda.js"

This sample page is available at ../sample19.html.

Mouse and touch events

Discovery

This Mouse and touch events page is available at ../touchtest.html.

Back