function _showDeviceAssociation( productId, feature ) {
		_stopDevicesRefresh();
		var html = '<h1>' + Utils.getLangString( _prefix + "_association" ) + '</h1>'
				+	'<h3>' + productId + ' - ' + feature.name + ' - ' + feature.deviceName + ' (#' + feature.deviceId + ')</h3>'
				+	'<div class="scenes_section_delimiter"></div>'
				+	'<div class="' + _prefix + '-toolbar">'
				+		'<button type="button" class="' + _prefix + '-help"><i class="fa fa-question fa-lg text-info" aria-hidden="true"></i>&nbsp;' + Utils.getLangString( _prefix + "_help" ) + '</button>'
				+	'</div>'
				+	'<div class="' + _prefix + '-explanation ' + _prefix + '-hidden">'
				+		Utils.getLangString( _prefix + "_explanation_association" )
				+	'</div>';

		// Get compatible devices
		var protocol = _indexDevices[ feature.deviceId.toString() ];
		var devices = [];
		$.each( api.getListOfDevices(), function( i, device ) {
			if ( device.id == feature.deviceId ) {
				return;
			}
			// Check if device is an external device
			var isExternal = false;
			if ( device.id_parent === _deviceId ) {
				if ( _indexDevices[ device.id.toString() ] == protocol ) {
					isExternal = true;
				}
			}
			// Check if device is compatible
			var isCompatible = false;
			for ( var j = 0; j < device.states.length; j++ ) {
				if ( ( device.states[j].service === SWP_SID ) || ( device.states[j].service === SWD_SID ) ) {
					// Device can be switched or dimmed
					isCompatible = true;
					break;
				}
			}
			if ( !isExternal && !isCompatible ) {
				return;
			}
			
			var room = ( device.room ? api.getRoomObject( device.room ) : null );
			if ( isExternal ) {
				devices.push( {
					"id": device.id,
					"roomName": ( room ? room.name : "_No room" ),
					"name": "(ZiGate) " + device.name,
					"type": 3,
					"isExternal": isExternal
				} );
			} else {
				devices.push( {
					"id": device.id,
					"roomName": ( room ? room.name : "_No room" ),
					"name": device.name,
					"type": 2,
					"isExternal": isExternal
				} );
			}
		} );
		// Get scenes
		$.each( jsonp.ud.scenes, function( i, scene ) {
			var room = ( scene.room ? api.getRoomObject( scene.room ) : null );
			devices.push( {
				"id": scene.id,
				"roomName": ( room ? room.name : "_No room" ),
				"name": "(Scene) " + scene.name,
				"type": 1
			} );
		} );

		// Sort devices/scenes by Room/Type/name
		devices.sort( function( d1, d2 ) {
			var r1 = d1.roomName.toLowerCase();
			var r2 = d2.roomName.toLowerCase();
			if (r1 < r2) return -1;
			if (r1 > r2) return 1;
			var n1 = d1.name.toLowerCase();
			var n2 = d2.name.toLowerCase();
			if (n1 < n2) return -1;
			if (n1 > n2) return 1;
			return 0;
		} );

		function _getCheckboxHtml( deviceId, association, level ) {
			var pressType = "short";
			if ( level === 1 ) {
				pressType = "long";
			}
			return	'<span class="ziblue-' + pressType + '-press" title="' + pressType + ' press">'
				+		'<input type="checkbox"' + ( association && ( $.inArray( parseInt( deviceId, 10 ), association[level] ) > -1 ) ? ' checked="checked"' : '' ) + '>'
				+	'</span>';
		}

		var currentRoomName = "";
		$.each( devices, function( i, device ) {
			if ( device.roomName !== currentRoomName ) {
				currentRoomName = device.roomName;
				html += '<div class="' + _prefix + '-association-room">' +  device.roomName + '</div>';
			}
			if ( device.type === 1 ) {
				// Scene
				html += '<div class="' + _prefix + '-association ' + _prefix + '-association-scene" data-scene-id="' + device.id + '">'
					+		'<label>'
					+			_getCheckboxHtml( device.id, feature.association.scenes, 0 )
					//+			_getCheckboxHtml( device.id, feature.association.scenes, 1 )
					+			'&nbsp;' + device.name + ' (#' + device.id + ')'
					+		'</label>'
					+	'</div>';
			} else {
				// Classic device (e.g. Z-wave)
				html += '<div class="' + _prefix + '-association ' + _prefix + '-association-device" data-device-id="' + device.id + '">'
					+		'<label>'
					+			_getCheckboxHtml( device.id, feature.association.devices, 0 )
					//+			_getCheckboxHtml( device.id, feature.association.devices, 1 )
					+			'&nbsp;' + device.name + ' (#' + device.id + ')'
					+		'</label>'
					+	'</div>';
			}
		} );

		html += '<div class="' + _prefix + '-toolbar">'
			+		'<button type="button" class="' + _prefix + '-cancel"><i class="fa fa-times fa-lg text-danger" aria-hidden="true"></i>&nbsp;'  + Utils.getLangString( _prefix + "_cancel" ) + '</button>'
			+		'<button type="button" class="' + _prefix + '-associate"><i class="fa fa-check fa-lg text-success" aria-hidden="true"></i>&nbsp;'  + Utils.getLangString( _prefix + "_confirm" ) + '</button>'
			+	'</div>';

		$( "#" + _prefix + "-device-association" )
			.html( html )
			.css( {
				"display": "block"
			} );

		_formerScrollTopPosition = $( window ).scrollTop();
		$( window ).scrollTop( $( "#" + _prefix + "-known-panel" ).offset().top - 150 );
	}
/**
	 * Show all devices and scene that can be associated and manage associations
	 */
Show all devices and scene that can be associated and manage associations
Show all devices and scene that can be associated and manage associations
function _showDeviceAssociation( productId, feature ) {
		_stopDevicesRefresh();
		var html = '<h1>' + Utils.getLangString( _prefix + "_association" ) + '</h1>'
				+	'<h3>' + productId + ' - ' + feature.name + ' - ' + feature.deviceName + ' (#' + feature.deviceId + ')</h3>'
				+	'<div class="scenes_section_delimiter"></div>'
				+	'<div class="' + _prefix + '-toolbar">'
				+		'<button type="button" class="' + _prefix + '-help"><i class="fa fa-question fa-lg text-info" aria-hidden="true"></i>&nbsp;' + Utils.getLangString( _prefix + "_help" ) + '</button>'
				+	'</div>'
				+	'<div class="' + _prefix + '-explanation ' + _prefix + '-hidden">'
				+		Utils.getLangString( _prefix + "_explanation_association" )
				+	'</div>';
		var protocol = _indexDevices[ feature.deviceId.toString() ];
		var devices = [];
		$.each( api.getListOfDevices(), function( i, device ) {
			if ( device.id == feature.deviceId ) {
				return;
			}
			var isExternal = false;
			if ( device.id_parent === _deviceId ) {
				if ( _indexDevices[ device.id.toString() ] == protocol ) {
					isExternal = true;
				}
			}
			var isCompatible = false;
			for ( var j = 0; j < device.states.length; j++ ) {
				if ( ( device.states[j].service === SWP_SID ) || ( device.states[j].service === SWD_SID ) ) {
					isCompatible = true;
					break;
				}
			}
			if ( !isExternal && !isCompatible ) {
				return;
			}
			var room = ( device.room ? api.getRoomObject( device.room ) : null );
			if ( isExternal ) {
				devices.push( {
					"id": device.id,
					"roomName": ( room ? room.name : "_No room" ),
					"name": "(ZiGate) " + device.name,
					"type": 3,
					"isExternal": isExternal
				} );
			} else {
				devices.push( {
					"id": device.id,
					"roomName": ( room ? room.name : "_No room" ),
					"name": device.name,
					"type": 2,
					"isExternal": isExternal
				} );
			}
		} );
		$.each( jsonp.ud.scenes, function( i, scene ) {
			var room = ( scene.room ? api.getRoomObject( scene.room ) : null );
			devices.push( {
				"id": scene.id,
				"roomName": ( room ? room.name : "_No room" ),
				"name": "(Scene) " + scene.name,
				"type": 1
			} );
		} );
		devices.sort( function( d1, d2 ) {
			var r1 = d1.roomName.toLowerCase();
			var r2 = d2.roomName.toLowerCase();
			if (r1 < r2) return -1;
			if (r1 > r2) return 1;
			var n1 = d1.name.toLowerCase();
			var n2 = d2.name.toLowerCase();
			if (n1 < n2) return -1;
			if (n1 > n2) return 1;
			return 0;
		} );
		function _getCheckboxHtml( deviceId, association, level ) {
			var pressType = "short";
			if ( level === 1 ) {
				pressType = "long";
			}
			return	'<span class="ziblue-' + pressType + '-press" title="' + pressType + ' press">'
				+		'<input type="checkbox"' + ( association && ( $.inArray( parseInt( deviceId, 10 ), association[level] ) > -1 ) ? ' checked="checked"' : '' ) + '>'
				+	'</span>';
		}
		var currentRoomName = "";
		$.each( devices, function( i, device ) {
			if ( device.roomName !== currentRoomName ) {
				currentRoomName = device.roomName;
				html += '<div class="' + _prefix + '-association-room">' +  device.roomName + '</div>';
			}
			if ( device.type === 1 ) {
				html += '<div class="' + _prefix + '-association ' + _prefix + '-association-scene" data-scene-id="' + device.id + '">'
					+		'<label>'
					+			_getCheckboxHtml( device.id, feature.association.scenes, 0 )
					+			'&nbsp;' + device.name + ' (#' + device.id + ')'
					+		'</label>'
					+	'</div>';
			} else {
				html += '<div class="' + _prefix + '-association ' + _prefix + '-association-device" data-device-id="' + device.id + '">'
					+		'<label>'
					+			_getCheckboxHtml( device.id, feature.association.devices, 0 )
					+			'&nbsp;' + device.name + ' (#' + device.id + ')'
					+		'</label>'
					+	'</div>';
			}
		} );
		html += '<div class="' + _prefix + '-toolbar">'
			+		'<button type="button" class="' + _prefix + '-cancel"><i class="fa fa-times fa-lg text-danger" aria-hidden="true"></i>&nbsp;'  + Utils.getLangString( _prefix + "_cancel" ) + '</button>'
			+		'<button type="button" class="' + _prefix + '-associate"><i class="fa fa-check fa-lg text-success" aria-hidden="true"></i>&nbsp;'  + Utils.getLangString( _prefix + "_confirm" ) + '</button>'
			+	'</div>';
		$( "#" + _prefix + "-device-association" )
			.html( html )
			.css( {
				"display": "block"
			} );
		_formerScrollTopPosition = $( window ).scrollTop();
		$( window ).scrollTop( $( "#" + _prefix + "-known-panel" ).offset().top - 150 );
	}
function _showDeviceAssociation ( productId , feature ) { _stopDevicesRefresh ( ) ; var html = '<h1>' + Utils . getLangString ( _prefix + "_association" ) + '</h1>' + '<h3>' + productId + ' - ' + feature . name + ' - ' + feature . deviceName + ' (#' + feature . deviceId + ')</h3>' + '<div class="scenes_section_delimiter"></div>' + '<div class="' + _prefix + '-toolbar">' + '<button type="button" class="' + _prefix + '-help"><i class="fa fa-question fa-lg text-info" aria-hidden="true"></i>&nbsp;' + Utils . getLangString ( _prefix + "_help" ) + '</button>' + '</div>' + '<div class="' + _prefix + '-explanation ' + _prefix + '-hidden">' + Utils . getLangString ( _prefix + "_explanation_association" ) + '</div>' ; var protocol = _indexDevices [ feature . deviceId . toString ( ) ] ; var devices = [ ] ; $ . each ( api . getListOfDevices ( ) , function ( i , device ) { if ( device . id == feature . deviceId ) { return ; } var isExternal = false ; if ( device . id_parent === _deviceId ) { if ( _indexDevices [ device . id . toString ( ) ] == protocol ) { isExternal = true ; } } var isCompatible = false ; for ( var j = 0 ; j < device . states . length ; j ++ ) { if ( ( device . states [ j ] . service === SWP_SID ) || ( device . states [ j ] . service === SWD_SID ) ) { isCompatible = true ; break ; } } if ( ! isExternal && ! isCompatible ) { return ; } var room = ( device . room ? api . getRoomObject ( device . room ) : null ) ; if ( isExternal ) { devices . push ( { "id" : device . id , "roomName" : ( room ? room . name : "_No room" ) , "name" : "(ZiGate) " + device . name , "type" : 3 , "isExternal" : isExternal } ) ; } else { devices . push ( { "id" : device . id , "roomName" : ( room ? room . name : "_No room" ) , "name" : device . name , "type" : 2 , "isExternal" : isExternal } ) ; } } ) ; $ . each ( jsonp . ud . scenes , function ( i , scene ) { var room = ( scene . room ? api . getRoomObject ( scene . room ) : null ) ; devices . push ( { "id" : scene . id , "roomName" : ( room ? room . name : "_No room" ) , "name" : "(Scene) " + scene . name , "type" : 1 } ) ; } ) ; devices . sort ( function ( d1 , d2 ) { var r1 = d1 . roomName . toLowerCase ( ) ; var r2 = d2 . roomName . toLowerCase ( ) ; if ( r1 < r2 ) return - 1 ; if ( r1 > r2 ) return 1 ; var n1 = d1 . name . toLowerCase ( ) ; var n2 = d2 . name . toLowerCase ( ) ; if ( n1 < n2 ) return - 1 ; if ( n1 > n2 ) return 1 ; return 0 ; } ) ; function _getCheckboxHtml ( deviceId , association , level ) { var pressType = "short" ; if ( level === 1 ) { pressType = "long" ; } return '<span class="ziblue-' + pressType + '-press" title="' + pressType + ' press">' + '<input type="checkbox"' + ( association && ( $ . inArray ( parseInt ( deviceId , 10 ) , association [ level ] ) > - 1 ) ? ' checked="checked"' : '' ) + '>' + '</span>' ; } var currentRoomName = "" ; $ . each ( devices , function ( i , device ) { if ( device . roomName !== currentRoomName ) { currentRoomName = device . roomName ; html += '<div class="' + _prefix + '-association-room">' + device . roomName + '</div>' ; } if ( device . type === 1 ) { html += '<div class="' + _prefix + '-association ' + _prefix + '-association-scene" data-scene-id="' + device . id + '">' + '<label>' + _getCheckboxHtml ( device . id , feature . association . scenes , 0 ) + '&nbsp;' + device . name + ' (#' + device . id + ')' + '</label>' + '</div>' ; } else { html += '<div class="' + _prefix + '-association ' + _prefix + '-association-device" data-device-id="' + device . id + '">' + '<label>' + _getCheckboxHtml ( device . id , feature . association . devices , 0 ) + '&nbsp;' + device . name + ' (#' + device . id + ')' + '</label>' + '</div>' ; } } ) ; html += '<div class="' + _prefix + '-toolbar">' + '<button type="button" class="' + _prefix + '-cancel"><i class="fa fa-times fa-lg text-danger" aria-hidden="true"></i>&nbsp;' + Utils . getLangString ( _prefix + "_cancel" ) + '</button>' + '<button type="button" class="' + _prefix + '-associate"><i class="fa fa-check fa-lg text-success" aria-hidden="true"></i>&nbsp;' + Utils . getLangString ( _prefix + "_confirm" ) + '</button>' + '</div>' ; $ ( "#" + _prefix + "-device-association" ) . html ( html ) . css ( { "display" : "block" } ) ; _formerScrollTopPosition = $ ( window ) . scrollTop ( ) ; $ ( window ) . scrollTop ( $ ( "#" + _prefix + "-known-panel" ) . offset ( ) . top - 150 ) ; }
Show all devices and scene that can be associated and manage associations
Show all devices and scene that can be associated and manage associations
// Get compatible devices // Check if device is an external device // Check if device is compatible // Device can be switched or dimmed // Get scenes // Sort devices/scenes by Room/Type/name // Scene //+			_getCheckboxHtml( device.id, feature.association.scenes, 1 ) // Classic device (e.g. Z-wave) //+			_getCheckboxHtml( device.id, feature.association.devices, 1 )