Access Keys:
Skip to content (Access Key - 0)

Current UIComposer implementation is still lacking in generalization and extensibility. Therefore adding a new protocol view takes quite some work and is error-prone. However, this document attempts to describe the steps.

An important thing to note is that the existing implementation holds its state on the client-side, making the implementation more complicated.

The parts described here are expected to undergo a complete redesign and refactoring in the next major (2.0) release of the UIComposer.

index.html

...
  <div id="tabs">
...
  <li>
    <a href="#x10_tab" class="has_icon">X10</a><span id="create_x10_icon" title="Create X10" class="ui-icon ui-icon-plusthick"></span>
  </li>

...

  <div id="x10_tab">
    <p> Click the plus image to create x10 button.</p>
    <div id="x10_container" class="item_container">
      <div class="clear"></div>
    </div>
    <div class="clear"></div>
  </div>

...
                
  <div id="create_x10_dialog">
    <form id="x10_form">
      <fieldset>
        <label for="x10_label_input">Label</label>
        <input type="text" id="x10_label_input" name="x10_label_input"/> 
        <label for="x10_address_input">Address</label>
        <input type="text" id="x10_address_input" name="x10_address_input"/> 
        <label for="x10_command_input">Command</label>
        <input type="text" id="x10_command_input" name="x10_command_input"/>
      </fieldset>
    </form>
  </div>

model/x10.js

var X10 = function() {
	function X10() {
		var self = this;
		Model.call(self);
                //text ui interface display
		self.label = "";
		self.address = "";
		self.command = "";

                /**
                 * Get HTML getElementId
                 */
		self.getElementId = function() {
			return "x10"+self.id;
		};
		
		self.inspectViewTemplate = "template/_x10Inspect.ejs";
	}

        /**
         * Create new instance from flat model (which have no private method).
         * @param model flat model (which have no private method).
         * @returns created new instance.
         */
	X10.init = function(model) {
		var x10 = new X10();
		x10.id      = model.id     ;
		x10.label   = model.label  ;
		x10.address = model.address;
		x10.command = model.command;
		return x10;
	};
    
	return X10;
}();

template/_x10Inspect.ejs

<label for="inspect_x10_label">Label</label>
<input type="text" class="text ui-widget-content ui-corner-all"  value="<%=label %>" id="inspect_x10_label">
<label for="inspect_x10_address">Address</label>
<input type="text" class="text ui-widget-content ui-corner-all"  value="<%=address %>" id="inspect_x10_address">
<label for="inspect_x10_command">Command</label>
<input type="text" class="text ui-widget-content ui-corner-all"  value="<%=command %>" id="inspect_x10_command">
<%InspectView.getModel= function() { %>
<% var model = $("#inspect_tool_bar").data("model"); %>
<% var label = $.trim($("#inspect_x10_label").val()); %>
<% var command = $.trim($("#inspect_x10_command").val()); %>
<% model.label = label;%>
<% model.command = command;%>
<% return model;%>
<% }; %>

view/protocolView.js

...

var X10View = function() {
    function X10View(x10) {
        var self = this;
        var _model = x10;

        self.getModel = function() {
            return _model;
        };

        self.getElement = function() {
            return $("#" + self.getModel().getElementId());
        };

        var init = function() {
            var btn = HTMLBuilder.X10BtnBuilder(self.getModel());
            var info = $("#x10_tab p");
            if (info.size() != 0) {
                info.remove();
            }
            btn.prependTo($("#x10_tab .item_container"));
        };

        init();

        self.deleteView = function() {
            self.getElement().remove();
        };

	self.updateView = function () {
            var x10 = self.getModel();
	    var btn = $("#"+x10.getElementId());
	    btn.interceptStr({
		text:x10.label,
		max:14
	    });
	};
    }

    return X10View;
} ();

htmlBuilder.js

...

        X10BtnBuilder: function(x10) {
            var button = HTMLBuilder.blueBtnBuilder(x10.label);

            button.addClass("x10_btn");
            button.addClass("iphone_element");
            button.attr("id", x10.getElementId());
            button.data("model", x10);
            button.attr("title", x10.label);

            return button;
        },
...

template/_controllerXML.js

Template for generating the controller.xml configuration file. Modify to add an entry to a new protocol event you plan on adding. Each event type has its own top-level event group (for example, <x10Events>, <knxEvents>).

...
(1)    <x10Events>
(2)      <% for (var index in events.x10Events.x10Event) {%>
(3)        <% var x10Event = events.x10Events.x10Event[index]; %>
(4)        <x10Event id="<%=x10Event.id %>" label="<%=x10Event.label %>" address="<%=x10Event.address %>" command="<%=x10Event.command %>"/>
(5)      <% } %>
(6)    </x10Events>
...

A code snippet from template/_controllerXML.js in UIComposer codebase.

In the code snippet above, line #1 shows the top-level <x10Events> XML tag. Line #2 starts a loop to go through all the X10 events (user interface buttons) the user has added to his model. Line #3 declares a x10Event variable to hold the next X10 event instance locally. On next line #4 a <x10Event> XML element is added with attributes whose values are fetched from the local x10Event variable fields (id, label, address and command). At the end, lines #5 and #6 close off the loop and XML <x10Events> element.

controller/protocolController.js

...
var X10Controller = function() {

	return {

        /**
         * Show create x10 button dialog.
         */
        showCreateX10Dialog:function () {
            $("#create_x10_dialog").showModalForm("Create X10", {
                buttons:{
                    'Create': X10Controller.confirmCreate
                },
                confirmButtonName:'Create',
                width:350
            });
        },
		
        /**
	 * Invoked when user confirm create x10 button.
	 */
	confirmCreate:function () {
	    var label = $("#x10_label_input");
	    var address = $("#x10_address_input");
	    var command = $("#x10_command_input");
	        
            $("#x10_form").validate({
                invalidHandler:function(form, validator) {
                    $("#create_x10_dialog").errorTips(validator);
                },

                showErrors:function(){},

                rules: {
                    x10_label_input: {
                        required: true,
                        maxlength: 50
                    },
                    x10_address_input: {
                        required:true,
                        maxlength: 50
                    },
                    x10_command_input: {
                        required:true,
                        maxlength: 50
                    }
                },

                messages:{
                    x10_label_input: {
                        required: "Please input a label",
                        maxlength: "Please input a label no more than 50 charactors"
                    },
                    x10_address_input: {
                        required: "Please input a address",
                        maxlength: "Please input a address no more than 50 charactors"
                    },
                    x10_command_input: {
                        required: "Please input a command",
                        maxlength: "Please input a command no more than 50 charactors"
                    }
                }
            });

            if ($("#x10_form").valid()) {
	        var x10 = new X10();
	        x10.id = global.BUTTONID++;
	        x10.label = label.val();
	        x10.address = address.val();
	        x10.command = command.val();

	        X10Controller.createX10(x10);
		
	        $("#create_x10_dialog").closeModalForm();
	    }
	},

	createX10: function(x10){
            var x10View = new X10View(x10);
	
	    x10.addDeleteListener(x10View);
	    x10.addUpdateListener(x10View);
			
	    var btn = x10View.getElement();
	    makeBtnDraggable(btn);
	    btn.inspectable();
        }
    };
}();
...

controller/tabController.js

...

    // Static methods -----------------------------------------------------------------------------

    TabController.init = function() {
        $("#tabs").tabs();
        $("#create_knx_icon").unbind().bind("click", KNXController.showCreateKNXDialog);
        $("#create_x10_icon").unbind().bind("click", X10Controller.showCreateX10Dialog);
        $("#create_http_icon").unbind().bind("click", HTTPController.showCreateHTTPDialog);
        $("#create_tcp_icon").unbind().bind("click", HTTPController.showCreateTCPDialog);
        $("#create_telnet_icon").unbind().bind("click", HTTPController.showCreateTelnetDialog);
        $("#select_command_icon").unbind().bind("click", selectCommand);
    };

    return TabController;

controller/downloadController.js

...
       /**
        * Gets all X10 events user has added.
        *
        * @returns x10Event array
        */
       function parseX10() {
(1)        var x10Events = new Array();
(2)        $("#x10_container").find(".x10_btn").each(function() {
(3)            var x10Event = new Object();
(4)            var model = $(this).data("model");
(5)            x10Event.id = model.id;
(6)            x10Event.address = model.address;
(7)            x10Event.command = model.command;
(8)            x10Event.label = model.label;
(9)            x10Events.push(x10Event);
           });

           return x10Events;
       }
...
...
    /*--------------------     generate irb file     --------------------------------------*/

    /**
     * Generate UI Interface description file.
     */
    function generatePanelDesc() {
        var screens = getStoredScreens();

        var macroBtns = new Array();
        $("#macro .macro_btn_defination").each(function() {
            var model = $(this).data("model");
            var btnModels = model.getSubModels();
            model.buttons = new Array();
            for (var index in btnModels) {
                model.buttons.push(btnModels[index]);
            }
            macroBtns.push(model);
        });

        var knxBtns = new Array();
        $("#knx_container").find(".knx_btn").each(function() {
            knxBtns.push($(this).data("model"));
        });
        var x10Btns = new Array();
        $("#x10_container").find(".x10_btn").each(function() {
            x10Btns.push($(this).data("model"));
        });
        var httpBtns = new Array();
        $("#http_container").find(".http_btn").each(function() {
            httpBtns.push($(this).data("model"));
        });
        var tcpBtns = new Array();
        $("#tcp_container").find(".tcp_btn").each(function() {
            tcpBtns.push($(this).data("model"));
        });


        var panel = {
            screens: screens,
            knxBtns: knxBtns,
            x10Btns: x10Btns,
            httpBtns: httpBtns,
            tcpBtns: tcpBtns,
            macroBtns: macroBtns,
            maxId: global.BUTTONID
        };

        var data = JSON.stringify({
            panel: panel
        });

        return data;
    }
...

controller-1.0-M3.xsd


<xsd:element name="events">
  <xsd:annotation>
    <xsd:documentation><![CDATA[
      The parent element of all kinds of event tags.
    ]]></xsd:documentation>
  </xsd:annotation>
  <xsd:complexType>
    <xsd:sequence>
      <xsd:choice minOccurs="0" maxOccurs="unbounded">
        <xsd:element ref="irEvents"/>
        <xsd:element ref="knxEvents"/>
        <xsd:element ref="x10Events"/>
      </xsd:choice>
    </xsd:sequence>
  </xsd:complexType>		
</xsd:element>

...

<xsd:element name="x10Events">
  <xsd:annotation>
    <xsd:documentation><![CDATA[
      The parent element of <x10Event> tags.
    ]]></xsd:documentation>
  </xsd:annotation>
  <xsd:complexType>
    <xsd:sequence>
      <xsd:element ref="x10Event" minOccurs="0" maxOccurs="unbounded"/>
    </xsd:sequence>
  </xsd:complexType>
</xsd:element>

<xsd:element name="x10Event">
  <xsd:annotation>
    <xsd:documentation><![CDATA[
      The event to control a device with X10 protocol.
    ]]></xsd:documentation>
  </xsd:annotation>
  <xsd:complexType>
    <xsd:attributeGroup ref="idAttr"/>
    <xsd:attribute name="label" type="xsd:string" use="optional"/>
    <xsd:attribute name="address" type="xsd:string" use="required"/>
    <xsd:attribute name="command" type="xsd:string" use="required"/>
  </xsd:complexType>
</xsd:element>

controller/importController.js

...
    /**
     * Invoked after upload success.
     * @param responseText responseText
     * @param statusText statusText
     */
    function uploadSuccess(responseText, statusText) {
        ImportController.cleanUp();
        var data = responseText;
        // notice: revert order is very important, don't change it if you are clear with it.
        revertKnxBtns(data.panel.knxBtns);
        revertX10Btns(data.panel.x10Btns);
        //revertHTTPBtns(data.panel.httpBtns);          // TODO !!
        revertMacroBtns(data.panel.macroBtns);
        revertMacroSubBtns(data.panel.macroBtns);
        revertScreens(data.panel.screens);

        global.BUTTONID = data.panel.maxId;
        $("#upload_form_container").closeModalForm();
        $.hideLoading();
    }

...

    /**
     * Revert X10 buttons	
     * @param x10Btns x10Btns object from description file
     */
    function revertX10Btns(x10Btns) {
        for (var index in x10Btns) {
            var btn = x10Btns[index];
            var model = ImportController.buildModel(btn);
            X10Controller.createX10(model);
        }
    }
...

Added by Juha Lindfors , last edit by Juha Lindfors on Jul 08, 2009 17:52

© 2008-2011 OpenRemote Inc. OpenRemote is a trademark of OpenRemote, Inc.
Adaptavist Theme Builder (3.3.3-conf210) Powered by Atlassian Confluence 2.10.3, the Enterprise Wiki.
Free theme builder license