Custom widgets: feature walkthrough

That is true. So maybe only store it until the config parameters are changed (better: only delete configuration for the parameters that got changed, keep the others)? Most times only the code will get changed, so that will still be a big benefit.
However that will need some more work to implement.

Edit: I just thought what happens to the already used widgets on dashboards after config parameters are changed? Is this also a point that is currently dangerous? Otherwise the preview widget could just be treated like a normal one, right?

I’d like to create a custom widget including a N3 chart. Unfortunately I haven’t seen any code for such a chart.

@ysc: would this be possible? How to get or extract code from a standard widget?

Thank you

@tailor See here, section “Reuse built-in widgets”:

In all theory you can spawn a chart with <widget-chart ng-model="..."></widget-chart> and extracting the model from an existing chart with the “Edit the local panel configuration” technique as described, however the charts are one of those widgets types like the knob which adjust their size automatically, so it’s more difficult to have it positioned correctly, you may have to tinker a bit.

It works with a set of 3 divs with absolute positioning:

<div style="position: absolute; top: 0; left: 0; width: 100%; height: 100%">
	<div
       style="position: absolute; top: 0; left: 0; width: 100%; height: 100%"
       ng-init='model=                {
                    "name": "Température",
                    "sizeX": 12,
                    "sizeY": 6,
                    "item": "Outside_Temperature",
                    "type": "chart",
                    "row": 6,
                    "col": 0,
                    "charttype": "interactive",
                    "service": "rrd4j",
                    "period": "W",
                    "axis": {
                        "y": {
                            "includezero": false
                        }
                    },
                    "series": [
                        {
                            "axis": "y",
                            "display_line": true,
                            "display_area": true,
                            "item": "Outside_Temperature",
                            "name": "Température ext.",
                            "color": "#FF0000"
                        },
                        {
                            "axis": "y",
                            "display_line": true,
                            "display_area": false,
                            "item": "MultiSensorSalon_Temperature",
                            "name": "Température int.",
                            "color": "#FFCC00"
                        },
                        {
                            "axis": "y2",
                            "display_line": false,
                            "display_area": true,
                            "item": "Outside_Pressure",
                            "name": "Pression atm.",
                            "color": "#336699"
                        }
                    ]
                }'>
  	<div style="position: absolute; top: 0; left: 0; width: 100%; height: 100%">
      <widget-chart ng-model="model"></widget-chart>
      <h3 style="position: absolute; left: 25%; top: 25%">This is a custom widget!</h3>
    </div>
  </div>
</div>

I want to create a simpler custom color picker based on this widget - I’d like it to be a button that has the current set color, and clicking the button pulls up the picker (kind of like a combo-box) to select from some pre-set colors.

But… I don’t know where to start. Can the lazy-load approach be used to pull in the js definition of the widget? Does anyone have an example of creating a widget that’s completely unlike the internal widgets from a separate js file?

Thanks,

Bruce

@ysc Hi Yannick
Thank you very much. I tried to implement the chart in a widget based on the Matrix template.

Selected Code

<div class="widget">
	<div class="graph">
         <div>
			<div
             ng-init='model=                {
                    "name": "CPU Load",
                    "sizeX": 12,
                    "sizeY": 6,
                    "item": "num_sysinfo_cpu_load",
                    "type": "chart",
                    "row": 6,
                    "col": 0,
                    "charttype": "interactive",
                    "service": "rrd4j",
                    "period": "4h",
                    "axis": {
                        "y": {
                            "includezero": false
                        }
                    },
                    "series": [
                        {
                            "axis": "y2",
                            "display_line": true,
                            "display_area": true,
                            "item": "num_sysinfo_cpu_load",
                            "name": "CPU Load",
                            "legend": false,
                            "color": "#FF0000"
                        }
                    ]
                }'>
				<div style="width: 100%; height: 250px">
					<widget-chart ng-model="model"></widget-chart>
				</div>
			</div>
		</div>	
	</div>	
</div>	

The resulting chart looks like this:
image

That a good initial result :grinning:

  1. Would it be possible to hide the legend (btw. why ist it on top of the chart?)?
  2. How about adjusting the size of the text?
  3. Any other adjustments?

Thank you very much in advance.

You can probably do all of those things with CSS. Can’t check now but the basic idea is to use the “Inspect” feature of your browser to figure out CSS classes and add CSS rules like display: none to hide the element or font-size to change the text size.

Hey Yannick,
thank you very much for this trick.
I tried to exchange the hardcoded item with a {{config.item}} but i think OH cant take user-created Variables or sth. like this.
You know any way to realise this?
Greetings Till

I try to build my own widget so I can use it for all my lights.
I have created a placeholder for an item under Settings. When I later assign an item to the widget, the name is displayed instead of the value of the item.
Actually the value ON or OFF should be in the widget?

If I use the standard widget “Switch” then it works.

What am I doing wrong?

Code:

<div ng-if="itemValue('config.room_item') === 'OFF'">
  <i ng-click="sendCmd('config.room_item', 'ON')" style="font-size:30px;" class="fa fa-lightbulb-o" aria-hidden="true"></i>
 </div>
{{config.room_item}}
{{config}}
<div ng-if="itemValue('config.room_item') === 'ON'">
  <i ng-click="sendCmd('config.room_item', 'OFF')" style="color:yellow;font-size:30px;" class="fa fa-lightbulb-o" aria-hidden="true"></i>
 </div>

bild

bild2

Remove the quotes around 'config.room_item'

1 Like

I’m trying to create a combined power, dimmer & color picker for my lights. I’d like the power, label, and color picker to be on one “line” (from left to right in that order) and the slider to be underneath all that on the next “line”. But when I try to do this, I get everything on it’s own line, so all 4 controls are stacked rather than being 3 on the top with the slider underneath. I thought enclosing the first 3 items in their own “div” might help this, but no luck. Here is my code:

<div ng-init='picker = {
    "name": "",
    "item": config.color,
    "style": "aCKolor"
};slider = {
    "name": "",
    "item": config.brightness,
    "floor": 1,
    "ceil": 100,
    "step": 10,
    "unit": "",
    "vertical": false,
    "hidelimits": true,
    "hidepointer": true,
    "hidelabels": true
};switch = {
    "name": config.name,
    "item": config.power,
    "hidelabel": true,
    "hideicon": false,
    "hideonoff": false
}'>
    <style>
    .cl-switch .switch {
      position: absolute;
      top: 0;
      width: 100%;
                }
    </style>
    <div class="btn-group">
      <widget-switch ng-model="switch"></widget-switch>
      <h4>config.name</h4>
      <widget-colorpicker ng-model="picker"></widget-colorpicker>
    </div>
    <widget-slider ng-model="slider" style="width: 90%; margin-top: -6px; display: block;" ></widget-slider>
    
</div>

Any suggestions on how I can get the first 3 widgets to be on the same row?

Thanks,

Bruce

1 Like

@ysc thank you.

Hi ,

i would create a custom widget an call this custom widget from another customer widget.
So I tried to setup a directive but the tpl html will be not loaded ? Can someone help ?
directive:

(function () {
    'use strict';
    angular      
    .module('app.widgets')
        .directive('shutter', function () {
            return {

                restrict: 'AE',
                scope: {
                    ngModel: '='
                },
                templateUrl: '/static/matrix-theme/shutter.html',
                controller: ['$controller', '$scope', function ($controller, $scope) {
                    debugger;
                    var myCtrl = $scope.ngModel;
                    return myCtrl;
                }],
                controllerAs: 'myCtrl',
            };
        })
        .config(function (WidgetsProvider) {
            debugger;
            WidgetsProvider.$get().registerType({
                type: 'shutter',
                displayName: 'Shutter',
                icon: 'download-alt',
                description: 'A button performing a certain action, like sending a command to an openHAB item'
            });
        });
});

Widget wich is calling the custom widget

<div oc-lazy-load="['/static/matrix-theme/shutter.js']">
                  	<shutter ng-model="rollershutter_1" ></shutter>
                  </div>
1 Like

Hi all,

I’m about to create a custom widget and im wondering if the following is possible, and if so… how?
If someone could help me or maybe find another way to get this working, that would be very much apprecciated.

I have the following code

<div>{{itemValue('Item_Name_1')}}</div>

and i have a config value named count as number

now i want to replace the 1 in the first code block with the config.count value.

thanks

<div>{{itemState('Item_Name_' + config.count.toString())}}</div>

should work.

1 Like

wow great! yes that works… Thank you very much :slight_smile:

this has been asked probably multiple times but i couldn’t find an answer… so i’ll give it a try:
are the codes for the “standard” widgets to be found somewhere? i’d like to modify the standard switch lightly but i don’t know where to begin…

thanks, but i’d like to start my custom widget on base of a standard widget and i have no idea how, just like @no.starm

You need to learn Angular JS (besides HTML and CSS):

1 Like