Template widget - tutorial & examples - make your own widget!

I just cant get it to work. i have done several changes but none of them brought the solution

<h4 style="color: #aabb00">Jarvis:</h4>
 <div class="row" style="background: blue;">
  <div class="col-md-4" style="height:50px;"><widget-icon iconset="'custom-icon'" icon="'jarvis-off'" size="50" state="itemValue('Online_Jarvis')=='ON' ? 'ON' : 'OFF'"></widget-icon></div>
   <div class="col-md-4 align-middle" style="height:50px;">Ping:</div>
  <div class="col-md-4" style="height:50px; color: red">{{itemValue('Ping_Jarvis')}}</div>
</div>

line-height:50px

These are css questions in general. I suggest you practice or read more.

Hi!

I want to create a monthly calender widget for my wall-mounted tablet.
Does anybody of you already implemented such a widget?

I found a calendar for angular/javascript which looks quite nice, called “ng-fullcalendar” (“https://www.npmjs.com/package/ng-fullcalendar”). What I understood is it could actually also create entries, not just displaying the days and events.
I thought because of the “ng” in the name it’s as simple to implement as the other Angular bootstrap widgets available, but sadly I wasn’t able to integrate it yet.
I tried to put the code in .js files, tried it also with app.component.ts and app.module.ts, all loaded via the lazy-load command, but I didn’t manged it.
Any ideas how that could be implemented?:thinking:

Alternatively, that calendar “https://codepen.io/bbarry/pen/Eopdk” or that “https://codepen.io/B8bop/pen/GhCAb” would also look fine.

Thank you for your help!
Caprisna

How to order a list by item value? I tried several things but none of them work.
I’m trying to get a list of the top 5 highest consuming devices.

anyone?

Sorry I can’t help, not an expert in angular by any means. What happens in the code you posted? Are the items sorted at all? Are they limited to 5?
The syntax seems correct to me, but again, not an expert.

Found this: Template Widget Example: Talking to Alexa - What's my Item Name?
Maybe just as simple as switching label to state?

Thanks, that did get me a step further. I got this now:

<div class="row" ng-repeat="item in itemsInGroup('gEnergyCons') | orderBy:'state':reverse | limitTo: 5">

Now it does order by item state, however they have a numerical value, but the orderBy sorts by the textual representation. So for example 90 > 100. Not what I want of course.
Also the reversing doesn’t work.
Don’t have more time now to play with it.

I suppose this is the same issue and possible solution: https://stackoverflow.com/questions/16764177/angular-orderby-number-sorting-as-text-in-ng-repeat

Hello again,
once more I have come to a problem. I would like to make this widget abit more interactive, so i added a ng-init. It woks fine on the dashboard but i can not get it to work on the widget-icon. Does anyone have an idea how to get that working?

<div ng-repeat-start="n in [].constructor(5) track by $index">
  <div ng-if="config.PanelGlobalNumber > $index" 
       ng-init="dashboard =config['Panel'+ ($index+1)];
                bild = config['bild'+($index+1)+'_iconset'];
                icon = config['bild'+($index+1)]">
    						      
		<table style="width: 100%; border-collapse: separate; border-spacing: 10px">
    <div ng-if="(config.dashboard)"/>
			<tr><td style="border: 4px solid #444444; border-radius: 10px;"><a class="dashboard-link" href="#/view/{{dashboard}}">{{dashboard}}, {{bild}}, {{icon}}<widget-icon iconset="{{bild}}" icon="{{bild}}" size="75" /></a></td></tr>
		</table>
  </div>
</div>
<div ng-repeat-end ng-if="(config.PanelGlobalNumber > $index +1)" />

image

A follow-up on my problem with displaying several items ordered by their state as a number. It took me quite some trial error and searching, but I finally came to a solution.

It seemed I couldn’t get around defining a sorter function to convert the state to a number. But this needs to be done in a separate js file, which you have to put in conf/html. So I created a file there named widgetcontroller.js with these contents:

    angular
    .module('app.widgets')
    	.controller('MyWidgetCtrl', ['$scope', function($scope) {

    	$scope.sorterFunc = function(item){
    		return -parseInt(item.state);
    	}
    }]);

Then the widget code needs to be as follows:

<div oc-lazy-load="['/static/widgetcontroller.js']">
  <div ng-controller="MyWidgetCtrl">
    <div class="row" ng-repeat="item in itemsInGroup('gEnergyCons') |  orderBy:sorterFunc | limitTo: 5">
      <div class="col-xs-8 text-right">{{item.label}}</div>
      <div class="col-xs-4 text-left">
        {{itemValue(item.name)*itemValue('EnergyVoltage_Global')/1000}}W
      </div>
    </div>
  </div>
</div>

And this finally gives me the top 5 consuming devices in my home.

3 Likes

Ok, look like i could understand this code?
You give a group of items into the sorter javascript and as item.state result you get a 0 or 1.
The orderBy uses the script via sorterFunc and the number of items will limit to a maximum of 5.
hope that i am right till this :slight_smile:

All OFF items get the same 0 as return value, all ON items the 1 and this will send to the item.name variable? Could not even see a sort function only the calculation with a .name item?? or did i missing something?

1 Like

The item state is a number, not an ON or OFF; it contains a value for the electrical current.
itemValue(item.name) gets the value of the item by passing the item.name to the itemValue() function. Then I multiply with a voltage to get the power consumption. The division by 1000 is because the current value is in milliamperes and I want my result in watts, not milliwatts.

Aaah, now it’s clear, thank you very much! Now i understand why you get different values out of the calculation (not only 1 or 0).

Hmm, try to make a easy grid, but it seems the array is build randomly in the sorting.

In the things i defined:

Group gAvtivities "AktivitÀt"
Group gLocations "Standorte"
Group gCol_01 "Licht" <'bulb'> (gActivities)
Group gCol_02 "Video" <'tv'> (gActivities)
Group gCol_03 "Audio" <'speaker'> (gActivities)

Group gRow_01 "Kueche" <'kitchen'>  (gLocations)
Group gRow_02 "Flur" <'wardrobe'> (gLocations)
Group gRow_03 "Schlafzimmer" <'sleep'> (gLocations)
Group gRow_04 "Bad" <'bath'> (gLocations)

if i start the widget i get a different order sometimes
 can i define a sort order for the itemsInGroup

<div class="row">
  <div class="col-xs-1"></div> 
  <div class="col-xs-1" ng-repeat="group in itemsInGroup('gActivities')">{{group.label}} {{group.name}}</div>
</div>

<div class="row text-left bg-primary" ng-repeat="group in itemsInGroup('gLocations')">{{group.label}} {{group.name}}</div>

sort

Thx for any advice

Got it solved:

<div class="col-xs-1" ng-repeat="group in itemsInGroup('gActivities') | orderBy:'name'">{{group.label}} {{group.name}}</div>

but why it’s called via name and not as expected via group.name or item.name


1 Like

nvm, I fixed my problem myself today :slight_smile: :muscle:t2:

<div class="row">
  <div class="col-xs-10"><span style="color: #26bf75; font-size: 14pt; font-weight:bold">{{itemValue('SNMP_DS415_SoftVersion')}}</span></div>
</div>
<div class="row">
  	<div ng-if="itemValue('SNMP_DS415_UpdStatus') == 'Latest Version'">
      <div style="color: #26bf75; font-size: 12pt">
        <div class="col-xs-10">{{itemValue('SNMP_DS415_UpdStatus')}}</div>
      </div>
    </div>
  	<div ng-if="itemValue('SNMP_DS415_UpdStatus') != 'Latest Version'">
      <div style="color: #bf2659; font-size: 12pt">
        <div class="col-xs-10">{{itemValue('SNMP_DS415_UpdStatus')}}</div>
      </div>
    </div>
</div>

Hey everyone!
I used the Search but couldnt find a solution for my Problem, maybe one of you can help me.

Currently i am creating a new Dashboard for my SmartHome Project, with some UI for Heating, Lights, Shutters etc. I am using the new-pride-theme which is based on the almost legendary Matrix Theme :smiley:

I have created a Custom Widgets for Heating:

    <div class="section">
	<div class="title">Heizung</div>
  <div class="widget" style="width:100%">
		<div class="icon off">
			<svg viewBox="0 0 48 48">
				<use xlink:href="/static/matrix-theme/squidink.svg#temp"></use>
			</svg>
		</div>
		<div class="name">Raumtemperatur</div>
		<div class="valueGroup">
			<div class="value">{{itemValue(config.actual_temperature) | number:1}} °C</div>
		</div>
	</div>
	<div class="widget" style="width:100%">
		<div class="icon off">
			<svg viewBox="0 0 48 48">
				<use xlink:href="/static/matrix-theme/squidink.svg#window"></use>
      </svg>
		</div>
		<div class="name">Fenster</div>
		<div class="valueGroup">
			<div class="value">{{itemValue(config.window_state)}}</div>
		</div>
	</div>
	<div>
		<div class="widget" style="width:100" ng-if="itemValue(config.control_mode) == 'AUTO-MODE'" ng-click="sendCmd(config.boost_mode, 'ON')">
			<div class="icon off">
				<svg viewBox="0 0 48 48">
					<use xlink:href="/static/matrix-theme/matrixicons.svg#off"></use>
        </svg>
			</div>
			<div class="name">Boost starten</div>
			<div class="valueGroup"></div>
		</div>
		<div class="widget" style="width:100%" ng-if="itemValue(config.control_mode) == 'BOOST-MODE'" ng-click="sendCmd(config.auto_mode, 'ON')">
			<div class="icon on">
				<svg viewBox="0 0 48 48">
					<use xlink:href="/static/matrix-theme/matrixicons.svg#on"></use>
				</svg>
      </div>
			<div class="name">Boost stoppen (Restzeit {{itemValue(config.boost_state)}} min)</div>
			<div class="valueGroup"></div>
		</div>
	</div>
    
	<div class="description">
		<div class="valueGroup">
			<div ng-init="knob = {
                    skin: {
    									type: 'tron',
                      width: 5,
    									spaceWidth: 3
  									},
                    options: {
                      barColor: '#57BD88',
  										trackWidth: 30,
  										barWidth: 30,
                    	step: 1,
                      textColor: 'white',
                      min: 10,
                      max: 28,
                      trackColor: '#656D7F',
                      unit: '°C'
                    }
                   };"></div>
			<div style="width:100%; text-align: center">
				<ui-knob value="itemValue(config.set_temperature)| number:0" options="knob.options" ng-click="sendCmd(config.set_temperature, knob.value)" />
			</div>
		</div>
	</div>
</div>
<!-- END Heizung --> 

Now i would like to somehow import this Widget inside another Widget, but it seems that this only works with the standard-HabPanel Components.

<li class="col-md-4"
                ng-init="models[light.name] = { name: light.label, item: light.name, step: 1 }">
                <div class="box" style="height: 150px; margin: 10px">
                    <widget-slider ng-model="models[light.name]"></widget-slider>
                </div>
            </li>

Do anyone have any suggestions how i can achieve this?

Hi All

Im trying to do some greater than, less than maths for the itemValue and change the color depending on what it is.

!=‘0’ works, ie icon on or icon off

What doesnt work is using a symbol.

ON (GREEN) should be if its greater than 0
OFF (RED) should be if its less than 0
OFF should be if its zero

     <div class="icon on" ng-if="itemValue('SE_Live_Export')!='0'"><svg viewBox="0 0 48 48"><use xlink:href="/static/ihp-theme/squidink.svg#thunder-1"></use></svg></div>
		<div class="icon off" ng-if="itemValue('SE_Live_Export')=='0'"><svg viewBox="0 0 48 48"><use xlink:href="/static/ihp-theme/squidink.svg#thunder-1"></use></svg></div>
  <div class="icon off red" ng-if="itemValue('SE_Live_Export')!='0'"><svg viewBox="0 0 48 48"><use xlink:href="/static/ihp-theme/squidink.svg#thunder-1"></use></svg></div>

I am doing a similar thing, changing the text color depending on the value and it works. Maybe it gives you a hint:

    <div ng-style="(itemValue(config.colorItem).split(' ')[0]-0) < config.threshold_1 && {'color':(config.text_color1)} || (itemValue(config.colorItem).split(' ')[0]-0) >= config.threshold_1 && (itemValue(config.colorItem).split(' ')[0]-0) < config.threshold_2 && {'color':(config.text_color2)} || (itemValue(config.colorItem).split(' ')[0]-0) >= config.threshold_2 && {'color':(config.text_color3)}">
      <div ng-style="{ 'font-size': config.font_size + 'pt' }">
        <div ng-if="config.format">{{config.format | sprintf:itemValue(config.item).split(' ')[0]}}</div>
        <div ng-if="!config.format">{{itemValue(config.item)}}</div>
      </div>
    </div>

Not really :frowning: but thank you