This page last changed on Apr 26, 2012 by ebariaux.
The basic need for this came from supporting VoIP/SIP on the iOS console (See this thread for more details).
But it can have many other uses as shown below.
The idea is that UI elements can be "linked to protocols" that are taken care of entirely by the console and that do not get back to the controller.
This means command executions that button, switches, sliders, ... trigger and sensor values bound to labels, images, switches, ...
This can be implemented in a totally transparent fashion at the modeler level.
A new client side protocol can be defined in the modeler as a current controller side protocol is.
The same "protocol.xml" configuration file is used to defined the protocol name and its properties.
If is however important that protocol names are unique (so a client and server side protocol do not share the same name), so that the protocol name alone is enough information to determine if it's client or server side.
So the modeler and the files it generates do not change.
The controller must however be able to make the distinction between the 2.
1. It must ignore the configuration of client side sensors, as it should not start any polling / listening thread for them.
2. Although there should never be any rest call to the controller to execute a write command from a client protocol, we should build in some safeguard in case a console that do not understand the concept of client protocol connects to it.
3. The controller must generate and return the appropriate information to the console so it can execute the local protocols locally
This is performed during the call to /rest/panel/<panel id> (or more specifically /rest/<version>/panel/<panel id> , where version is > 2.0).
In the 2.1 API, we can define the XML returned by that call as
<?xml version="1.0" encoding="UTF-8"?>
<screen id="211" name="Light" inverseScreenId="218">
<group id="142" name="Livingroom">
<include type="command" ref="46" />
<include type="command" ref="47" />
<include type="sensor" ref="44" />
<include type="command" ref="48" />
<sensor id="43" name="Shade1_Level" type="level" />
<sensor id="44" name="Light1" type="switch">
<include type="command" ref="54" />
<state name="on" />
<state name="off" />
<command id="46" protocol="SIP">
<property name="command" value="MUTE_ON" />
This last <local> section, is generated by the controller as it knows the commands and sensors that are linked to a client side protocol.
It has the same schema as the elements that are present in the controller.xml file.
Note that the XML returned by that call, although only being a subset of the full panel.xml file, still uses the same schema.
It means that the panel.xsd needs to be updated to support that optional <local> element at the end.
The console now has that extra information in <local> and can use to to "intercept" calls to commands, sensor read and poll and execute them locally.
It does mean that the console will need to map the client side protocols to some specific implementation, just as the controller does for server side ones.
Whether or not the exact same CommandBuilder mechanism is implemented should still be decided.
This can be used in different situation:
- for very specific client side protocols such as SIP/VoIP mentioned above
- to interface with the OR console : status of connection with controller, status of polling but maybe also login, logout, back, next, settings, ... replacing the very specific navigation commands that are currently in place (to be seen if generic commands add value here)
- to interface with the device : WiFi status, battery level, ...
- to have some server less control : it can be possible to have some basic control through TCP or HTTP, directly from the console (e.g. iPhone) to the device.
Those client side protocols should still be limited to very specific cases, as they are heavy to support, requiring most likely a specific implementation for each console (so currently iOS, Android and Web).
So if the Designer generates additional optional elements (<local>) for panel.xml then the controller requires no changes at all, since it has no interest in what goes on inside the panel.xml definitions, no?
Posted by juha at Apr 26, 2012 15:39
Also, if controller requires knowledge of how to handle these changes that go into the panel.xml, it complicates the usefulness of this feature for serverless mode, I think?
Posted by juha at Apr 26, 2012 15:43
Indeed, changing the modeler does make more sense.
In that situation, the controller.xml would never contain any client specific protocol definitions, so in my controller changes above
1. is solved and no changes are required
2. is handled by the normal error handling and no changes are required
3. will still require a small modification but that should be straight forward. This XML generation is currently handled by ProfileServiceImpl.getProfileDocumentByPanelName method, which is very aware of the XML format. So this code should be updated to copy over the local section.
The modeler now needs to be aware of client side protocols, so
in the protocol.xml definitions, add a flag to indicate the protocol is client side
<protocol displayName="SIP Client" tagName="sip" client="true">
There should be no impact on the user interface of the modeler, client and server side protocol are handled the same way.
But when the panel.xml / controller.xml files are generated, the flag is taken into account so that:
- only elements linked to server side protocols are used to generate controller.xml
- elements linked to client side protocols are used to generate the additional local section in panel.xml
Posted by ebariaux at Apr 26, 2012 16:53
I haven't really thought about how the console could get its configuration in an environment where there is no controller at all but indeed having the controller do this job would make things more complicated (or duplicate functionality).
I don't wont to tackle implementation of this right now but indeed, the idea would be that then a console could connect directly to beehive to get the information it needs. So when the URL in the console is that of Beehive, ask a user name/password and then beehive can serve the list of panels and the panel descriptions directly to the console and the controller is fully out of the loop.
We should have some validation in this case that only client side protocols can be used.
This is compatible with the changes outlined above, as when I describe the fact that the panel.xml/controller.xml generation is changed, I mention the modeler but really it is/should be beehive doing that generation (and the one serving that up to the controller).
Posted by ebariaux at Apr 26, 2012 16:59
Posted by juha at Apr 26, 2012 19:49
Indeed, there is a lot of crap the designer is doing right now which belongs to the backend (Beehive) and downloading and exporting the artifacts (zip) is one of them, currently implemented in the ResourceServiceImpl.java (and related classes). The current implementation generates all other sorts of issues as well, some of which the new cache implementation attempts to cover but the correct long term solution is another REST service on Beehive backend. Modularize the backend and lighten the crud on Designer. Helps with high availability deployments too, plus will be used by many other services that require the same data access – one of which is the serverless mode.
Posted by juha at Apr 26, 2012 20:02
I think modifying the designer to generate a panel.xml with additional <local> tags is more logic then using the current model and have the controller perform a translation from controller.xml into panel.xml.
Regarding controller-less setups this should also be much easier.
Posted by mredeker at Apr 27, 2012 08:58
I went ahead and had a first go at the implementation and noticed that same tags in the <local> section would conflict with identically named tags in the <screens> section.
For instance, button is defined both in the panel and controller XML schema. They are however different.
One way to handle this is to not re-use the controller schema for the <local> tag elements but create specific tags.
Another way would be to use appropriate namespaces on the elements.
I noticed however that both schemas were using the same http://www.openremote.org as their namespace.
So I changed both of them to use their specific namespace, http://www.openremote.org/panel and http://www.openremote.org/controller respectively.
I can now have the panel schema include the controller schema and have the <local> tag reference tags from the controller schema, as in:
<xsd:element ref="ctrl:components" minOccurs="0" maxOccurs="1"/>
<xsd:element ref="ctrl:sensors" minOccurs="0" maxOccurs="1"/>
<xsd:element ref="ctrl:commands" minOccurs="0" maxOccurs="1"/>
And in the generated panel.xml, the <local> tag looks something like
<ctrl:include type="command" ref="2"/>
Posted by ebariaux at May 07, 2012 12:13
This namespace change appear to be the correct, but will not break the old controllers ?
If current controllers will be fine, no problem, but if current controllers break probably will be better to use http://www.openremote.org/panel for new elements, and prepare the controllers to be able to accept the changes and make the namespace change for old elements later.
Posted by ivanfm at May 07, 2012 13:46
Changing the namespace on the controller side does indeed require a code change in the controller.
Looking at the number of places where the http://www.openremote.org namespace identifier is used currently makes this look like a non-trivial change.
Changing the namespace for panel-side only would limit the impact of this change.
Particularly given that ultimately we do want to work our way back to a single namespace and schema definition for all elements so that the controller can control the client's view in a dynamic way.
Posted by juha at May 07, 2012 23:58