Hi all,
I would like to announce a new feature merged yesterday into HABPanel: the ability to provision widgets through HABPanel’s configuration, instead of manually uploading .json to individual panel configurations files using the GUI.
What this feature notably allows is that from now on, widgets can easily be distributed as bundles (or part of bundles) installed to your openHAB installation like any another - for instance, by dropping them into the addons
directory or perhaps using the Eclipse IoT Marketplace. And since a few widgets need additional assets to work (stylesheets, iconsets, even scripts), they can also be distributed and registered in the bundle as a single “professional” package suited for more complex widgets.
I prepared an example implementation to showcase a typical scenario; this example widget controls a control for a rollershutter, which comes with:
- some icons;
- a stylesheet (so the template can use CSS classes instead of inline styling);
- the widget itself: this file is actually the .json file you would export from HABPanel’s custom widget list.
The OSGi component (RollershutterWidgetProvider.java) will then, upon activation:
- register the icons in
icons/
as a standard iconset (it extendsAbstractResourceIconProvider
); - map the static resources in the
static/
folder to a dedicated path on theHttpService
inactivate()
line 127; - read the widget’s .json file from the bundle and add its contents as a new property to HABPanel’s configuration, also in
activate()
line 134 - I chose this approach instead of a dedicated class because it’s simple enough and in order to avoid any depedency to the HABPanel bundle.
deactivate()
will unregister everything - the static resources and the configuration variable.
The name of these configuration properties must be widget.<your_widget_id>
i.e. they should begin with “widget.
”, followed by an unique id (be careful, there are no id collision protection measures).
Once the bundle is installed:
openhab> bundle:list
...
246 | Active | 80 | 2.1.0.201704182210 | Rollershutter widget example for HABPanel
It will simply pick up the configuration proprties; the widgets will show up in HABPanel’s widget list and “Add widget” menu:
There are icons and tooltips to make the distinction between “globally provisioned” and “user-defined” custom widgets. As indicated, a globally provisioned widget cannot be modified within the GUI, but can be cloned to a user-defined widget you can then modify.
Regarding usage, it behaves like any other widget. Simply drop it into a dashboard:
You might notice the new icons - they actually come from the iconset registered by the bundle along with the widget. Here’s the widget’s template:
<div class="example-rollershutter" oc-lazy-load="['/habpanel-resources/example-widget/rollershutter.css']">
<div class="rollershutter-header">{{ngModel.name}}</div>
<button class="btn btn-default up-button" ng-click="sendCmd(config.item, 100)">
<img src="/icon/fts_shutter_up?iconset=knx-rollershutter&format=svg" class="invert"></img>
</button>
<div class="middle-buttons">
<button class="btn btn-primary button-left" ng-click="sendCmd(config.item, 30)">
<img src="/icon/fts_shutter_30?iconset=knx-rollershutter&format=svg"></img>
</button>
<button class="btn btn-primary button-middle" ng-click="sendCmd(config.item, 50)">
<img src="/icon/fts_shutter_50?iconset=knx-rollershutter&format=svg"></img>
</button>
<button class="btn btn-primary button-right" ng-click="sendCmd(config.item, 70)">
<img src="/icon/fts_shutter_70?iconset=knx-rollershutter&format=svg"></img>
</button>
</div>
<button class="btn btn-default down-button" ng-click="sendCmd(config.item, 0)">
<img src="/icon/fts_shutter_down?iconset=knx-rollershutter&format=svg" class="invert"></img>
</button>
</div>
Also note how the stylesheet is lazy-loaded from the registered static resources path, then the classes from it simply applied to the HTML elements. Next I’ll try to come up with another example including custom scripting (https://jsfiddle.net/jbf2f7k7/2/)
My hope is that this new feature will pave the way to a better distribution and provisioning mechanism for widgets; I invite you to play with the sample project and don’t hesitate to ask questions or provide feedback!
Cheers