CF iViewer

This wiki will focus on interfacing with the iViewer product from *CommandFusion which is available for Android and Apple iOS platforms.
iViewer provides users the ability to create a custom graphical user interface on their mobile device that controls almost any networked device.

By using the CF iViewer interface, you can create a custom gui for your DomotiGa system that updates and controls you Home Automation system in real time across multiple iPads/mobile devices.

The DomotiGa iViewer "eco-system"

The DomotiGa iViewer "eco-system" consists of Four components:

1. CommandFusion guiDesigner

The GUI designer software runs on a Windows PC and is where you design and define the gui and application logic that will run in on your mobile device (in iViewer). You can define a complete gui via the guiDesigner program, however for more complex GUI's you'll want to develop and integrate customised JavaScript code into your GUI. The designed gui (and the javascripts) is loaded up to your mobile device from the guiDesigner via an integrated upload tool. Once on the iPad/Andriod, the gui is rendered by the iViewer app and runs independent of the guiDesigner (ie. as a standalone app on your mobile device - no server is needed).
guiDesigner is free to download and use.

2. CommandFusion iViewer

This is the App that runs the gui as designed and scripted in guiDesigner. It is avalable for Android and iOS platforms. iViewer supports all Ethernet communications methods including TCP Client/Server, UDP Unicast/Multicast/Broadcast, HTTP/HTTPS. Communications with DomotiGa CF iViewer interface is via TCP.
There are 3 license models available for iViewer.
Free, Lite and Pro. The key restriction with the Free version is it is limited to a single page and Lite is limited to 10 pages. See here for details. http://www.commandfusion.com/software/iviewerlite

3. The DomotiGa CF iViewer interface.

This interface provides a TCP Server to which the iViewer app(s) connects as a client. It is distributed as part of DomotiGa and is available under "Remote Control" in the "Interfaces" drop down menu. The CF IViewer interface provides the following functions:
- Accepts multiple concurrent iViewer clients (session remains connected - reducing overhead and improving responsiveness).
- Automatically send DomotiGa device updates to all connected iViewer clients
- iViewer client can request current device states for all (non-hidden) devices
- iViewer client can request request current device states for single device
- caters for a heartbeat message (though this is not required in most cases)
- Performs translation of specific states...ie. translates "On" and "Off" for switches to "1" and "0" and "Dim 0"/"Dim 100" to "0"/"100" for dimmers before sending to iViewer.

4. JSONRPC Interface

This is the preferred interface for sending external commands to DomotiGa (replacing the XML-RPC interface). While select specialised commands have been coded into the CF iViewer interface, (ie.request current device states for all devices), the iViewer gui should use the JSONRPC interface for sending commands to DomotiGa (ie. to turn on/off a light). This requires some simple JavaScript code (to send json requests) to be deployed as part of the iViewer gui. Sample code is provided below. For example, when a button is pressed on the gui to turn on a light, this code is called with the required parameter (ie. to turn on light with device ID of "1" you would send {"jsonrpc": "2.0", "method": "device.set", "params": {"device_id": 1, "value": "Off"}, "id": 1})

DomotiGa/iViewer Eco-System Diagram

<insert diagram here>

     devices-domotiga-CFIiViewer interface <-> iViewer-GuiDesigner <-> other devices
                             -> jsonrpc           

Setting up the iViewer interface in DomotiGa

Video Tutorial: Step 1. Basic Integration
Video Tutorial: Step 1. Basic Integration
See Attached Tutorial1.rar at the bottom of this wiki page.

Video Tutorial: Step 2. Using Javascript, guages, serial and analog joins - and making it pretty
See Attached Tutorial2.rar at the bottom of this wiki page.

Video Tutorial: Step 3a. Full Control - Sendin g commands to DomotiGa using jsonrpc
See Attached Tutorial3a.rar at the bottom of this wiki page.

Oh...probably the trickiest part is getting the feedback rule Reg-ex correct...in this case the ruse is "^69_value1=(\d*)" which will match the data sent by domotiGa CF iViewer for device 69, value 1 (Domotiga will send "69_value1=1" when the switchchanges to on/1, and "69_value1=0" when it changes to off/0).
Basically the regex means:
^ the match needs to be at the start of the string (ie. will not match 169, only 69)
69 DomotiGa Device ID 69
_value1= text sent my Domotiga to identify this as "value1" of the DomotiGa device
(\d*) One or more decimal digits, up until the end of the message field (\x03).

CIViewer.class interface in detail

- Format of data
Let's assume you have a device in Domotiga called "Power Consumption" which has a DeviceID of "70" and three values, value 1, value 2, and value 3.
These might represent the instantaneous power (value 1), power used in the last hour (Value 2) and total power used (value 3)
Let's assume value 1 changes to 100, value2 changes to 1021 but value 3 does not change yet.
When an update occurs to one of these values in DomotiGa, a call is made to the the CF iViewer module (actually CIViewer.class) to send the updated value to any connected iViewer clients (via the established TCP session).
The data is sent as raw TCP in the following format:
<deviceId>_value<ValueNum>=<Value><HEX03>

In the above example, this would result in the following being sent to all connected iViewer clients in real time.

70_value1=30\x0370_value1=30\x03

Important Note: the \x03 represents a single byte/hex code of 03

- Handling of dimmers/switches
- debug information
- known issues

guiDesigner - Defining the DomotiGa system in System manager.

Handling device updates in iViewer

- Feedback rules
- Regex examples and traps
- using Javascript to process feedback
- Brief example and links for integrating other systems (eg. UDP updates) into iViewer

Sending commands from to DomotiGa from iViewer using JSONRPC

- Handling device states - ie. How to use a single button for On and Off.
- Pro's and cons/ examples of sending commands directly to other devices (ie. not via domotiGa...say an IR blaster)

Example CF javascript and Interfaces

Basic Javascript to refresh status from DomotiGa, show connection state & Refresh Connection
save this code to a file in your guiDesigner project...name it something like main.js You then use the Script Manager in guiDesigner to add this script to your giu.

// Callback function for DomotiGa System status change
function onDomotiGaSystemConnectionStatusChange(system, connected, remote) {
    if (connected) {
        CF.log(system + " System is CONNECTED to " + remote); //Print a status message to the debug log
        CF.setJoin("d" + joinDomotiga, 1);                                        //Set the DomotiGa icon to "on" (coulored icon)
        CF.send(system, "SendDeviceStatusAll\x03");                    //Send a command to DomotiGa CF iViewer interface, requesting it so send curent status of all (active) devices.
    }
    else {
        CF.setJoin("d" + joinDomotiga, 0);
        CF.log(system + " System not connected");
    }
}

// This function disconnects and reconnects to a system.
// I have attached it to a button on the gui so i can manually force a re-connect attempt (to DomotiGa)
// It addresses an issue in the current version if iViewer where iViewer times out and stops trying to connect to an "Always On" system and so may look like it's connected when it is not.
function DisconnectReconnect(system) {
    CF.setSystemProperties(system, {enabled: false});
    CF.setSystemProperties(system, {enabled: true});
}

CF.userMain = function () {

    joinDomotiga = 1;        // <---CHANGE THIS to digital join number for the icon indicating a connection to DomotiGa

    // Watch for important system connects and disconnects
    // IMPORTANT:  If you named your domotiga system something other than "DomotiGa", you'll need to change the text "DomotiGa" 
    // =========   in following line to match the system name in System manager.
    //
    CF.watch(CF.ConnectionStatusChangeEvent, "DomotiGa", onDomotiGaSystemConnectionStatusChange, true);  // <--- CHANGE THIS to match the DomotiGa system name defined in System manager
};

Basic code to send a coommand to domotiga to turn on, off or dim a light/device.

// This is called by pressing a button in the GUI - eg. to toggle a light on or off depending upon the button's current state.
//
// This function checks the current state of the button, and passes either paramValueOnCommand or paramValueOffCommand to SendJsonCommandToDomotiGa depending upon the current state of the button
// You would call this from a button in the gui by putting something like the following in the Basic Action/Javascript field
//       SendCommandToDomotiGaByButtonState({"jsonrpc": "2.0", "method": "device.set", "params": {"device_id": 41, "value": "On" }, "id": 1},{"jsonrpc": "2.0", "method": "device.set", "params": {"device_id": 41, "value": "Off" }, "id": 1},[join])
//
// The [join] parameter is evaluated when the button is pressed, and sends the join type&number of the button (eg. "d2") if the button was assigned Digital Join 2
// If (in this example) "d2" was off (ie =0), then we send the On parameter to DomotiGa otherwise we send the Off one.
//
// The current state of the buttons is set by a feedback rule (defined through guidesigner) and is updated via DomotiGa iViewer sending status updates to connected devices.
//      ie.  you would see something like this in in the DomotiGa logs when the light is set to on (100%).
//           2013/10/04 12:55:59 [iViewer] SendUpdateDevice: Study_Light_value :100
//
function SendCommandToDomotiGaByButtonState(paramValueOnCommand, paramValueOffCommand, buttonJoin) {
    CF.getJoin(String(buttonJoin), function (join, value, tokens) {
        // regardless of the join type, the value is always a string
        // if we want a number, we need to use parseInt() or parseFloat()
        if (value == 0) {
            SendJsonCommandToDomotiGa(paramValueOnCommand)
        } else {
            SendJsonCommandToDomotiGa(paramValueOffCommand)
        }
    });
}

// Set Send an JSON-RPC command to DomotiGa server
function SendJsonCommandToDomotiGa(rBody) {
    CF.log("SendJsonCommandToDomotiGa: rBody : ");
    CF.logObject(rBody);
    try {
        var Parameters = {"Content-Type": "application/json"};

        var host = "http://192.168.0.13:9090/";
        CF.request(host, "POST", Parameters, JSON.stringify(rBody), function (status, headers, body) {
            try {
                if (status == 200) {
                    var data = JSON.parse(body);
                    if (data.error !== undefined) {
                        self.lastError = data.error;
                        CF.log("ERROR REPLY ---------");
                        CF.logObject(self.lastError);
                    } else {
                        Object.keys(data).forEach(function (keyTag) {
                            CF.log("Domotiga Returned Data..." + keyTag + ":" + data[keyTag]);
                        });
                    }
                } else {
                    self.lastError = (typeof(body) == "string" && body.length > 0) ? body : "HTTP status: " + status;
                    CF.log("ERROR REPLY ---------");
                    CF.logObject(self.lastError);
                }
            } catch (e) {
                CF.log("Exception caught while processing response from SendJsonCommandToDomotiGa: " + e);
            }
        });
    } catch (e) {
        CF.log("Exception caught in SendJsonCommandToDomotiGa: " + e);
    }
}

This code is called as follows from buttons or sliders in CommandFusion iViewer.

Slider:

SendJsonCommandToDomotiGa({"jsonrpc": "2.0", "method": "device.set", "params": {"device_id": 41, "value": "dim " + data }, "id": 1})

Separate buttons for On and Off

SendJsonCommandToDomotiGa({"jsonrpc": "2.0", "method": "device.set", "params": {"device_id": 41, "value": "On" }, "id": 1})

SendJsonCommandToDomotiGa({"jsonrpc": "2.0", "method": "device.set", "params": {"device_id": 41, "value": "Off" }, "id": 1})

Single "stateful" button handling both On and Off

SendCommandToDomotiGaByButtonState({"jsonrpc": "2.0", "method": "device.set", "params": {"device_id": 41, "value": "On" }, "id": 1},{"jsonrpc": "2.0", "method": "device.set", "params": {"device_id": 41, "value": "Off" }, "id": 1},[join])

- Simple example of how feedback is handled
- simple example of sending command via jsonrpc

Debugging

- Examples of common issues and how to debug using Hercules and iViewer iViewer Remote Monitor and JavaScript debugger

Tools

  • Hercules - TCP Client Very handy for seeing what is being sent from the CF iViewer interface.
  • "Wireshark":http//www.wireshark.org/download.html Handy to examine the format of the jsonrpc calls being sent to DomotiGa from iViewer.

Requirements

Prowl has the following requirements:
  • DomotiGa 1.0.xxx (revision xxxx) or higher

Resources

* About CommandFusion
Founded in Melbourne, Australia in 2005, the company has been selling its flagship software product (CommandFusion iViewer) for iOS since 2008. Renowned for its flexibility and versatility, iViewer is now available for both iOS and Android platforms. iViewer provides users the ability to create a custom graphical user interface on their mobile device that controls almost any networked device. CommandFusion recently released its first hardware line in 2012. The hardware range provides a cost effective, modular system that provides the ability to tie many different systems together to allow for a central control point and automation. With a small, dynamic and driven international team coming from the automation, software and hardware fields, CommandFusion strives to offer the best support and fastest innovation turnaround in the industry.

This wiki-page TODO list

  • Complete missing sections.
  • Add images (and embed videos?)
  • Add example gui's and javascript code

  • Added by kasteleman about 3 years ago

    Hello there.....just another issue in the script mentioned above?

    You say:

    CF.send(system, "SendDeviceStatusAll\u0003"); //Send a command to DomotiGa CF iViewer interface, requesting it so send curent status of all (active) devices.

    That did not work for me. Had to change it to:
    CF.send(system, "SendDeviceStatusAll\x03");
    Otherwise DomotiGa the result is:

    2014/01/09 18:31:22 [IViewer] Data from socket 0 192.168.2.110 :S
    2014/01/09 18:31:22 [IViewer] Data from socket 0 192.168.2.110 :e
    2014/01/09 18:31:22 [IViewer] Data from socket 0 192.168.2.110 :n
    2014/01/09 18:31:22 [IViewer] Data from socket 0 192.168.2.110 :d
    2014/01/09 18:31:22 [IViewer] Data from socket 0 192.168.2.110 :D
    2014/01/09 18:31:22 [IViewer] Data from socket 0 192.168.2.110 :e
    2014/01/09 18:31:22 [IViewer] Data from socket 0 192.168.2.110 :v
    2014/01/09 18:31:22 [IViewer] Data from socket 0 192.168.2.110 :i
    2014/01/09 18:31:22 [IViewer] Data from socket 0 192.168.2.110 :c
    2014/01/09 18:31:22 [IViewer] Data from socket 0 192.168.2.110 :e
    2014/01/09 18:31:22 [IViewer] Data from socket 0 192.168.2.110 :S
    2014/01/09 18:31:22 [IViewer] Data from socket 0 192.168.2.110 :t
    2014/01/09 18:31:22 [IViewer] Data from socket 0 192.168.2.110 :a
    2014/01/09 18:31:22 [IViewer] Data from socket 0 192.168.2.110 :t
    2014/01/09 18:31:22 [IViewer] Data from socket 0 192.168.2.110 :u
    2014/01/09 18:31:22 [IViewer] Data from socket 0 192.168.2.110 :s
    2014/01/09 18:31:22 [IViewer] Data from socket 0 192.168.2.110 :A
    2014/01/09 18:31:22 [IViewer] Data from socket 0 192.168.2.110 :l
    2014/01/09 18:31:22 [IViewer] Data from socket 0 192.168.2.110 :l

    because end of the message field (\x03) is not send

    Now it shows:

    2014/01/09 18:33:43 [IViewer] Data from socket 0 192.168.2.110 :
    2014/01/09 18:33:43 [IViewer] SendDeviceStatusAll
    2014/01/09 18:33:43 [IViewer] Client0: 192.168.2.110 :48_value1=1
    2014/01/09 18:33:43 [IViewer] Client0: 192.168.2.110 :50_value1=0
    2014/01/09 18:33:43 [IViewer] Client0: 192.168.2.110 :51_value1=Away
    2014/01/09 18:33:43 [IViewer] Client0: 192.168.2.110 :52_value1=1
    2014/01/09 18:33:43 [IViewer] Client0: 192.168.2.110 :55_value1=1
    2014/01/09 18:33:43 [IViewer] Client0: 192.168.2.110 :61_value1=34
    2014/01/09 18:33:43 [IViewer] Client0: 192.168.2.110 :66_value1=9604 4
    2014/01/09 18:33:43 [IViewer] Client0: 192.168.2.110 :67_value1=0
    2014/01/09 18:33:43 [IViewer] Client0: 192.168.2.110 :70_value1=1
    2014/01/09 18:33:43 [IViewer] Client0: 192.168.2.110 :71_value1=1
    2014/01/09 18:33:43 [IViewer] Client0: 192.168.2.110 :72_value1=0
    2014/01/09 18:33:43 [IViewer] Client0: 192.168.2.110 :74_value1=1
    2014/01/09 18:33:43 [IViewer] Client0: 192.168.2.110 :80_value1=Off
    2014/01/09 18:33:43 [IViewer] Client0: 192.168.2.110 :83_value1=21.0
    2014/01/09 18:33:43 [IViewer] Client0: 192.168.2.110 :51_value2=-21
    2014/01/09 18:33:43 [IViewer] Client0: 192.168.2.110 :83_value2=21
    2014/01/09 18:33:43 [IViewer] Client0: 192.168.2.110 :84_value1=0
    2014/01/09 18:33:43 [IViewer] Client0: 192.168.2.110 :85_value1=Off
    2014/01/09 18:33:43 [IViewer] Client0: 192.168.2.110 :86_value1=On
    2014/01/09 18:33:43 [IViewer] Client0: 192.168.2.110 :87_value2=22.5

    Small note aside:using commandfusion 2.7.0.1108

    • Added by thechad about 3 years ago

      Hi Hans.

      i am not sure what's happening with your setup, however \u0003 and \x03 are equivalent....

      I just tested this on my system using the files from Tutorial 3a and receive the following (correct) output....

      2014/01/11 20:03:14 [IViewer] Got connect from client with IP 192.168.0.222
      2014/01/11 20:03:14 [IViewer] Data from socket 0 192.168.0.222 :S
      2014/01/11 20:03:14 [IViewer] Data from socket 0 192.168.0.222 :e
      2014/01/11 20:03:14 [IViewer] Data from socket 0 192.168.0.222 :n
      2014/01/11 20:03:14 [IViewer] Data from socket 0 192.168.0.222 :d
      2014/01/11 20:03:14 [IViewer] Data from socket 0 192.168.0.222 :D
      2014/01/11 20:03:14 [IViewer] Data from socket 0 192.168.0.222 :e
      2014/01/11 20:03:14 [IViewer] Data from socket 0 192.168.0.222 :v
      2014/01/11 20:03:14 [IViewer] Data from socket 0 192.168.0.222 :i
      2014/01/11 20:03:14 [IViewer] Data from socket 0 192.168.0.222 :c
      2014/01/11 20:03:14 [IViewer] Data from socket 0 192.168.0.222 :e
      2014/01/11 20:03:14 [IViewer] Data from socket 0 192.168.0.222 :S
      2014/01/11 20:03:14 [IViewer] Data from socket 0 192.168.0.222 :t
      2014/01/11 20:03:14 [IViewer] Data from socket 0 192.168.0.222 :a
      2014/01/11 20:03:14 [IViewer] Data from socket 0 192.168.0.222 :t
      2014/01/11 20:03:14 [IViewer] Data from socket 0 192.168.0.222 :u
      2014/01/11 20:03:14 [IViewer] Data from socket 0 192.168.0.222 :s
      2014/01/11 20:03:14 [IViewer] Data from socket 0 192.168.0.222 :A
      2014/01/11 20:03:14 [IViewer] Data from socket 0 192.168.0.222 :l
      2014/01/11 20:03:14 [IViewer] Data from socket 0 192.168.0.222 :l
      2014/01/11 20:03:14 [IViewer] Data from socket 0 192.168.0.222 :
      2014/01/11 20:03:14 [IViewer] SendDeviceStatusAll
      2014/01/11 20:03:14 [IViewer] Client0: 192.168.0.222 :30_value1=3
      2014/01/11 20:03:14 [IViewer] Client0: 192.168.0.222 :34_value1=-22.1
      2014/01/11 20:03:14 [IViewer] 41_value1: sValue:Off
      2014/01/11 20:03:14 [IViewer] Client0: 192.168.0.222 :41_value1=0
      2014/01/11 20:03:14 [IViewer] Client0: 192.168.0.222 :43_value1=27.125
      2014/01/11 20:03:14 [IViewer] Client0: 192.168.0.222 :50_value1=22.75
      2014/01/11 20:03:14 [IViewer] Client0: 192.168.0.222 :58_value1=1300
      2014/01/11 20:03:14 [IViewer] Client0: 192.168.0.222 :69_value1=1
      2014/01/11 20:03:14 [IViewer] Client0: 192.168.0.222 :70_value1=36
      2014/01/11 20:03:14 [IViewer] Client0: 192.168.0.222 :72_value1=1327
      2014/01/11 20:03:14 [IViewer] Client0: 192.168.0.222 :111_value1=24.75
      .
      .
      .
      

      the main.js contains the same code as above. ie.

              CF.send(system, "SendDeviceStatusAll\u0003");   
      

      Having said that, I have edited the above code to now use \x03 to remove any confusion.

      If you are ok with it, can we remove these comments and follow this up on the forum so as not to confuse the wiki readers?

  • Added by pservais almost 3 years ago

    Nice to see other people are also working with iViewer. Thank you for showing the Eve screenshot, I almost forgot about it.

    • Added by johanvandyck over 1 year ago

      Hi

      If I go a little bit beyond the video, I found I quite difficult to programm. A simple example: a motion detector with value on/off instead of "1", "0".
      - create a button (see video's)
      - create a feedback rule
      choose a digital join
      add a regex like this "^52_value1=(\w*)"
      --> device ID 52 with value1 can have two values "On" and "Off". The catch I've lost a few days with "\w*" and not "\d*". The "d" stands for numbers, the "w" for alpha chararters.

      - define on value as "On" (without quotes)
      - define Off value as "Off" (without quotes)
      2015/09/24 22:18:41 [IViewer] Client0: 192.168.1.4 :52_value1=On
      

  • Added by Alexie about 1 year ago

    FYI

    I am working on another CF iViewer module, for integrating it with DomotiGa. Which should be easier to build/maintain then the current one ... Also the plan is to deprecate the 'iViewer' plugin and directly connect to the JSON-RPC via WebSockets (possible in version 1.0.022 ;-)).

Updated by: thechad, Updated about 3 years ago
Access count: 66232

Attached Files

Tutorial 1.rar - Video Tutorial: Step 1. Basic Integration (5.1 KB) thechad, 01/08/2014 01:09 PM

Tutorial 2.rar - Video Tutorial: Step 2. Using javascript, guages, serial and analog joins (426 KB) thechad, 01/10/2014 01:09 PM

Tutorial 3a.rar - Video Tutorial: Step 3a. Full Control - Sending commands to DomotiGa using jsonrpc (425 KB) thechad, 01/11/2014 07:38 AM

Also available in: PDF HTML TXT