New Pride Theme for HabPanel (Based on Matrix Theme) - Optimized for iPhone

Can you share me that widget which you edit for pride theme like widget in your post? i am not dev so edit widget in matrix theme is not easy for me.

I’m also very interested in how you achieved the lights by room layout.

@gorzan14 Can you share your current progress?

@eikowagenknecht Do you mean this?
Tablet:


Mobile phone:

It’s not finished yet. I’m not a developer. Just as scriptkiddie, using code of pmpkk. For now the widget loops through rooms given in first group. For each room it loops through the lights of this room given in the second group with all lights. I edited so that dimmer items are shown too. but up to now you can only switch them on or off.

Settings and screenshot of widget code


Screenshot of important part of code:

Widget code
<!-- 
Widget with Lights and Shutters in two Lists / Sections
You should scale widget full width an full length on Site / dashboard or more
Widget needs a group with all lights (switch, color, dimmer allowed) and a group with all rooms that should be shown
This widget is build from parts of the matrix-theme widgets
 -->

 <!-- Section Lights -->
 <div class="section" ng-init="hueColors = [ { hsb: '0,0,100', hex: '#fff' }, { hsb: '74,78,100', hex: '#fecc2f' }, { hsb: '46,100,100', hex: '#f9a228' }, { hsb: '26,100,100', hex: '#f6621f' }, { hsb: '0,100,100', hex: '#db3838' }, { hsb: '273,100,100', hex: '#a363d9' }, { hsb: '201,100,100', hex: '#40a4d8' }, { hsb: '177,100,100', hex: '#33beb8' }, { hsb: '140,100,100', hex: '#b2c225' } ]">
	<div class="sectionIconContainer">
        <div class="sectionIcon"><svg viewBox="0 0 48 48"><use xlink:href="/static/matrix-theme/matrixicons.svg#light_bulb"></use></svg></div>
    </div>
    <div class="title"><div class="name">Lights</div>
        <div ng-repeat="test in itemsInGroup(config.item_group_lights) | filter:query as arrLights"></div>
        <div class="summary"> ON: {{ ((arrLights | filter: { type: 'Dimmer' }).length - (arrLights | filter: { type: 'Dimmer', state: '0' } : true).length) + (arrLights | filter: { state: 'ON' }).length }} of {{arrLights.length}}</div>
    </div>
    <div class="controls">
        <!-- loop through all Rooms -->
        <div ng-repeat="room in itemsInGroup(config.item_group_rooms)">
            <div class="sub-title"><div class="name">{{room.label}}</div>
             	<!-- <div class="summary">{{room.label}}  -  ON: {{ ( filtered | filter: { state: 'ON' } ).length }} of {{filtered.length}}</div> -->
          	</div>
            <!-- loop through all lights in a room -->
            <div ng-repeat="item in arrLights | filter:{groupNames: room.name} | filter:query as filtered">
                <!-- Hue Color lights -->
                <div class="widget" ng-if="item.type=='Color' && itemValue(item.name + '_rgb')=='0,0,0'" ng-click="showHueSelect = !showHueSelect">
                    <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" ng-if="!config.config_light_names"><div class="hue" ng-style="{'background': 'rgb(' + itemValue(item.name + '_rgb') + ')'}"></div><div class="hueSelect" ng-init="showHueSelect = false" ng-show="showHueSelect"><div class="hueSelectItem"></div><div class="hueSelectOptions"><a href="" ng-click="sendCmd(item.name, 'OFF')"><svg viewBox="0 0 48 48" style="stroke: white; stroke-width: 3px;"><use xlink:href="/static/matrix-theme/matrixicons.svg#cross-line"></use></svg></a><a href="" ng-click="sendCmd(item.name, color.hsb)" ng-repeat="color in hueColors" ng-style="{ 'background': color.hex }"></a></div></div>{{item.label}}</div>
                    <div class="name" ng-if="config.config_light_names"><div class="hue" ng-style="{'background': 'rgb(' + itemValue(item.name + '_rgb') + ')'}"></div><div class="hueSelect" ng-init="showHueSelect = false" ng-show="showHueSelect"><div class="hueSelectItem"></div><div class="hueSelectOptions"><a href="" ng-click="sendCmd(item.name, 'OFF')"><svg viewBox="0 0 48 48" style="stroke: white; stroke-width: 3px;"><use xlink:href="/static/matrix-theme/matrixicons.svg#cross-line"></use></svg></a><a href="" ng-click="sendCmd(item.name, color.hsb)" ng-repeat="color in hueColors" ng-style="{ 'background': color.hex }"></a></div></div>{{item.name}}</div>
                </div>
                <div class="widget" ng-if="item.type=='Color' && itemValue(item.name + '_rgb')!='0,0,0'" ng-click="showHueSelect = !showHueSelect">
                    <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" ng-if="!config.config_light_names"><div class="hue" ng-style="{'background': 'rgb(' + itemValue(item.name + '_rgb') + ')'}"></div><div class="hueSelect" ng-init="showHueSelect = false" ng-show="showHueSelect"><div class="hueSelectItem"></div><div class="hueSelectOptions"><a href="" ng-click="sendCmd(item.name, 'OFF')"><svg viewBox="0 0 48 48" style="stroke: white; stroke-width: 3px;"><use xlink:href="/static/matrix-theme/matrixicons.svg#cross-line"></use></svg></a><a href="" ng-click="sendCmd(item.name, color.hsb)" ng-repeat="color in hueColors" ng-style="{ 'background': color.hex }"></a></div></div>{{item.label}}</div>
                    <div class="name" ng-if="config.config_light_names"><div class="hue" ng-style="{'background': 'rgb(' + itemValue(item.name + '_rgb') + ')'}"></div><div class="hueSelect" ng-init="showHueSelect = false" ng-show="showHueSelect"><div class="hueSelectItem"></div><div class="hueSelectOptions"><a href="" ng-click="sendCmd(item.name, 'OFF')"><svg viewBox="0 0 48 48" style="stroke: white; stroke-width: 3px;"><use xlink:href="/static/matrix-theme/matrixicons.svg#cross-line"></use></svg></a><a href="" ng-click="sendCmd(item.name, color.hsb)" ng-repeat="color in hueColors" ng-style="{ 'background': color.hex }"></a></div></div>{{item.name}}</div>
                </div>
                <!-- Switch lights -->
                <div class="widget" ng-if="item.type=='Switch' && itemValue(item.name)=='OFF'" ng-click="sendCmd(item.name, '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" ng-if="!config.config_light_names">{{item.label}}</div>
                    <div class="name" ng-if="config.config_light_names">{{item.name}}</div>
                </div>
                <div class="widget" ng-if="item.type=='Switch' && itemValue(item.name)=='ON'" ng-click="sendCmd(item.name, 'OFF')">
                    <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" ng-if="!config.config_light_names">{{item.label}}</div>
                    <div class="name" ng-if="config.config_light_names">{{item.name}}</div>
                </div>
                <!-- Dimmable lights -->
                <div class="widget" ng-if="item.type=='Dimmer' && itemValue(item.name)>0" ng-click="sendCmd(item.name, 'OFF')">
                    <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" ng-if="!config.config_light_names">{{item.label}} <div class="value">{{itemValue(item.name)}}%</div></div>
                    <div class="name" ng-if="config.config_light_names">{{item.name}} <div class="value">{{itemValue(item.name)}}%</div></div>
                </div>
                <div class="widget" ng-if="item.type=='Dimmer' && itemValue(item.name)==0" ng-click="sendCmd(item.name, '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" ng-if="!config.config_light_names">{{item.label}} <div class="value">{{itemValue(item.name)}}%</div></div>
                    <div class="name" ng-if="config.config_light_names">{{item.name}} <div class="value">{{itemValue(item.name)}}%</div></div>
                </div>
                <!-- Not initialized Lights -->
                <div class="widget" ng-if="(item.type=='Switch' || item.type=='Dimmer') && itemValue(item.name)=='NULL'" ng-click="sendCmd(item.name, 'ON')">
                    <div class="icon off" ><svg viewBox="0 0 48 48"><use xlink:href="/static/matrix-theme/matrixicons.svg#none"></use></svg></div>
                    <div class="name" ng-if="!config.config_light_names">{{item.label}}</div>
                    <div class="name" ng-if="config.config_light_names">{{item.name}}</div>
                </div>
            </div>
        </div>
    </div>
</div>

Not workin / in progressg: Hue (for me), room name / label switch, dimmer value formating, dimming.

LightsByRooms_List_Matrix_Pride_Style.widget.json (10.0 KB)

1 Like

Great work so far. I spent quite some time on this myself yesterday before I saw your answer. I got some things working: Switch, Dinmer (with slider), Color items. But I‘m missing others like the number of lights turned on. I‘ll have a look at your version and try to merge with mine and post the result here when it‘s done :slight_smile:

@eikowagenknecht it would be very nice to see your results.
Additional info: I use the pride.css but the light count formatting i copied from matrix .css for element <div class= “summary“> to have the nice box.

1 Like

First of all - thx for the great theme - it’s the reason I started to play with habpanel :wink:

Just wanted to share a bit different approach to charts - I use grafana a lot but there was always the problem with https://myopenhab.org/ (remote access) and local grafana as probably many of you noticed, unless using image rendering, which is a bit slow, at least on my rpi (+ latest graphana does not support rendering out of the box on ARM AFAIK at the moment) - and did not want to use any additional hardware unless really needed.

Therefore played a bit with habpanel build-in chart widget - so instead of using

<div class="graph">
			<img width="250" height="100" src="..." />
			<div class="legend">Last 24 hours</div>
    </div>

I use

    <div class="graph">
			<div ng-init='model_nik={
                    "type": "chart",
                    "charttype": "interactive",
                    "service": "influxdb",
                    "period": "D",
		            "axis": {
                      "y": { "ticks": 5 },
                      "y2": { "enabled": true },
                    },
		            "series": [
                        {
                            "axis": "y",
                            "display_line": true,
                            "display_area": false,
                            "item": "FF_Nik_Room_temperature",
                            "name": "Temperature",
                            "color": "var(--pride-2-color)"
                        },
                        {
                            "axis": "y2",
                            "display_line": true,
                            "display_area": true,
                            "item": "FF_Nik_Room_humidity",
                            "name": "Humidity",
                            "color": "#2389da"
                        }
                    
                    ]
                }'>

        	<div class="widget-chart-container">
	      		<widget-chart ng-model="model_nik"></widget-chart>          
	        </div>
        </div>
    </div>

and result

The main benefit is that the charts are now accessible through home.myopenhab.org (i.e. https://home.myopenhab.org/habpanel/index.html#/view/test2 for my test/wip dashboard) with zero additional setup (no reverse proxy, …) + charts being interactive, as the habpanel chart widget is.

While graphana is much more powerful, but for the stuff I need the build-in habpanel chart widget is more than enough - no graphana needed - and chart loading is instantaneous (while graphana rendering took a couple of seconds on my rpi). Just an idea if someone might find it useful. The dashboard is still WIP, but wanted to share the progress :wink:

EDIT: forgot to add the changes in pride-theme.css - I commented out the original .graph section and added the below content to the end of the css file:

.graph {
	width: 100%;
}
.widget-chart-container {
	height: 230px;
}
.graph .box-content {
	padding: 0px;
}
.graph .chart-tooltip {
	background-color: #808080;
}

EDIT2: attaching complete css as requested: pride-theme.css (25.2 KB)

2 Likes

I encountered a few problems on the way, e.g. https://github.com/openhab/openhab-webui/issues/218. And some things are still not working just the way I want them to. Main issue is that the dimmer sliders don’t work on small displays (say iPhone). Have to do some CSS fixing for that probably. I’ll make sure to post my results when they are in a usable state. Can’t be long now (I hope) :slight_smile:

Ok. Thank you.

I added a super simple script that calculate average of last 1h - first 30 mins compared to last 30 minutes of the hour - and based on that posts an update

  • 1 if temperature is raising,
  • 0 if temperature did not change,
  • -1 if temperature is falling.

val updateDiff = [ GenericItem sourceItem, GenericItem item, double limit, String name, int offset |

  val n = 30

  var nn = 0
  var double avgPre = 0
  var double avg = 0

  var i = 2 * n + 1
  while(( i = i - 1 ) >= n) {
    val historicState = sourceItem.historicState(now.minusMinutes(i + offset))
    if (historicState !== null) {
      var y = (historicState.state as DecimalType).doubleValue
      avgPre = avgPre + y
      nn = nn + 1
    }
  }

  avgPre = avgPre / nn

  nn = 0
  i = n + 1
  while(( i = i - 1 ) >= 0) {
    val historicState = sourceItem.historicState(now.minusMinutes(i + offset))
    if (historicState !== null) {
      var y = (historicState.state as DecimalType).doubleValue
      avg = avg + y
      nn = nn + 1
    }
  }

  avg = avg / nn
  val diff = avg - avgPre

  //logInfo("TTM", "result {}: {} <- {} vs {}", name, diff, avgPre, avg)

  if (diff > limit) {
    item.postUpdate(1)
  } else if (diff >= -limit) {
    item.postUpdate(0)
  } else {
    item.postUpdate(-1)
  }

]


rule "Temperature Trend Monitor"
when
    Time cron "1 * * * * ?"
then
  updateDiff.apply(Outside_ds18b20_temperature, Outside_ds18b20_temperature_slope, 0.35, "Outdoor", 0)
  updateDiff.apply(FF_Nik_Room_temperature, FF_Nik_Room_temperature_slope, 0.10, "Nik's Room", 0)
  updateDiff.apply(FF_Bed_Room_temperature, FF_Bed_Room_temperature_slope, 0.10, "Eva's Room", 0)
end

Script takes readings from i.e. Outside_ds18b20_temperature and sets value of Outside_ds18b20_temperature_slope - which is used as below:

	<div class="bigDash">
		<div class="description">Outdoor</div>
    <div class="top">
			<div class="icon on"><svg viewBox="0 0 48 48"><use xlink:href="/static/matrix-theme/squidink.svg#thermometer-3"></use></svg></div>
			<div class="value">
				<div class="main">{{itemValue('Outside_ds18b20_temperature') - 0.5 | number:0}}</div>
        <div class="decimals">.{{(itemValue('Outside_ds18b20_temperature') * 10 % 10 | number:0)}}</div>
				<div class="sub">&#176C</div>
				<div class="trend up" ng-if="itemValue('Outside_ds18b20_temperature_slope') == 1">
          <svg viewBox="0 0 48 48"><use xlink:href="/static/matrix-theme/squidink.svg#top-arrow-2"></use></svg>
        </div>
				<div class="trend" ng-if="itemValue('Outside_ds18b20_temperature_slope') == 0">
          <svg viewBox="0 0 48 48"><use xlink:href="/static/matrix-theme/matrixicons.svg#equal"></use></svg>
        </div>
				<div class="trend down" ng-if="itemValue('Outside_ds18b20_temperature_slope') == -1">
          <svg viewBox="0 0 48 48"><use xlink:href="/static/matrix-theme/squidink.svg#down-arrow-2"></use></svg>
        </div>
			</div>
		</div>

resulting in

Suggestions for better alternative more than welcome :slight_smile:

1 Like

So, here’s my version of the lights template. Thanks @gorzan14 for his input :slight_smile:

//EDIT:

  • Fixed group dimmers displaying x.000000% instead of x%
  • For switch lights, clicking the name now also toggles the light
  • Added percent sign to sliders
  • Removed unneeded slider options
  • Added space between value and % sign according to SI standards. If your preference is otherwise, replace all occurrences of " %" with “%” :wink:

Preview iPhone X:

Preview iPad:

Features:

  • It handles Switches, Dimmers, Color, Switch group, Dimmer group and Color group items.
  • Clicking the circle turns the light on / off, clicking the name opens the modal with dimmer / color settings.
  • Rooms and lights are sorted alphabetically.

Hints / prerequisites:

  • For Dimmer items, an additional Switch item is needed with the name suffix _sw, eg. Light_Living_Room_sw for Light_Living_Room. This is because sending “ON” to a Dimmer item sets it to full brightness while sending “ON” to those proxy Switch items restores them to the previous brightness (which i prefer). I opened a detailed bug report under https://github.com/openhab/openhab-addons/issues/7326 if anyone is interested in fixing this thoroughly.
  • All the lights need to be in one group (in my example “g_EG_Licht”)
  • There needs to be a Group for every Room. Those also have to be in a Group.

Example group definition:

Group g_EG_Licht    "Licht Erdgeschoss"
Group g_EG          "Erdgeschoss"
Group g_EG_Bad      "Bad"           (g_EG)
Group g_EG_Buero    "Büro"          (g_EG)
Group g_EG_Wohnen   "Wohnen"        (g_EG)

Example Dimmer definition with proxy switch item:

Dimmer  EG_Buero_Hue_Decke          "Büro Decke"            <lightbulb> (g_EG_Licht, g_EG_Buero)
Switch  EG_Buero_Hue_Decke_sw // Workaround switch, linked to the brightness channel of the thing

Example item definition to switch a whole group of dimmers at once:

Group:Dimmer:MAX g_EG_Wohnen_Hue_Ast	"Wohnen Ast"			<lightbulb> (g_EG_Licht, g_EG_Wohnen) { autoupdate="false" }
Group:Switch:OR(ON,OFF) g_EG_Wohnen_Hue_Ast_sw { autoupdate="false" } 
Dimmer	EG_Wohnen_Hue_Ast_1				"Wohnen Ast 1"			<lightbulb>	(g_EG_Wohnen_Hue_Ast)
Switch	EG_Wohnen_Hue_Ast_1_sw (g_EG_Wohnen_Hue_Ast_sw) 
Dimmer	EG_Wohnen_Hue_Ast_2				"Wohnen Ast 2"			<lightbulb>	(g_EG_Wohnen_Hue_Ast)
Switch	EG_Wohnen_Hue_Ast_2_sw (g_EG_Wohnen_Hue_Ast_sw) 
Dimmer	EG_Wohnen_Hue_Ast_3				"Wohnen Ast 3"			<lightbulb>	(g_EG_Wohnen_Hue_Ast)
Switch	EG_Wohnen_Hue_Ast_3_sw (g_EG_Wohnen_Hue_Ast_sw) 
Dimmer	EG_Wohnen_Hue_Ast_4				"Wohnen Ast 4"			<lightbulb>	(g_EG_Wohnen_Hue_Ast)
Switch	EG_Wohnen_Hue_Ast_4_sw (g_EG_Wohnen_Hue_Ast_sw) 
Dimmer	EG_Wohnen_Hue_Ast_5				"Wohnen Ast 5"			<lightbulb>	(g_EG_Wohnen_Hue_Ast)
Switch	EG_Wohnen_Hue_Ast_5_sw (g_EG_Wohnen_Hue_Ast_sw)

Template:

<div oc-lazy-load="[
                   '/static/matrix-theme/jquery-3.2.1.min.js',
                   '/static/matrix-theme/matrix.js',
                   '/static/matrix-theme/lights.js' ]">

<!--
Colors (in this order):
  bright (Hue App)
  concentrate (Hue App)
  dimmed (Hue App)
  red (Google Assistant)
  green (Google Assistant)
  blue (Google Assistant)
  purple (Google Assistant)
-->
  
<div class="section" ng-controller="lightsController" ng-init="hueColors = [
                                                              { hsb: '30,64,100', hex: '#ffad5c' },
                                                              { hsb: '73,2,100', hex: '#ffffff' },
                                                              { hsb: '30,64,31', hex: '#4f361c' },
                                                              { hsb: '0,100,100', hex: '#ff0000' }, 
                                                              { hsb: '122,100,100', hex: '#00ff08' }, 
                                                              { hsb: '251,100,100', hex: '#2f00ff' }, 
                                                              { hsb: '278,100,100', hex: '#a100ff' } ]">
  
	<div class="sectionIconContainer">
    <div class="sectionIcon">
      <svg viewBox="0 0 48 48"><use xlink:href="/static/matrix-theme/matrixicons.svg#light_bulb"></use></svg>
    </div>
  </div>

	<div class="title">
    <div class="name">Beleuchtung</div>
		<div ng-repeat="discard in itemsInGroup('g_EG_Licht') | filter:query as allLights"></div> <!-- TODO: Find a better way to handle this -->
    <div class="summary">{{(allLights | lightsOn).length}} von {{allLights.length}} eingeschaltet</div>
  </div>
  
  <div class="controls">
    <div ng-repeat="room in itemsInGroup('g_EG') | orderBy:'label'"> <!-- | filter:{ type: 'group' } -->
      <div class="sub-title">
        <div class="name">{{room.label}}</div>
      </div>
    
			<div ng-repeat="light in allLights | filter:{groupNames: room.name} | filter:query as roomLights">
        <!-- Options for slider, see https://github.com/angular-slider/angularjs-slider -->
			  <div ng-init="sliderModel = { 
                        name: 'brightness',
                        item: light.name,
                        unit: ' %',
                        floor: 0,
                        ceil: 100,
                        step: 5,
                        hidelabel: true,
                        hidelimits: true
                      };"></div>

        <!-- Switch, Group Switch -->
        <div class="widget" ng-if="(light.type=='Switch' || (light.type==='Group' && light.groupType==='Switch')) && getLightState(light)=='OFF'">
          <div class="icon off" ng-click="sendCmd(light.name, 'ON')"><svg viewBox="0 0 48 48"><use xlink:href="/static/matrix-theme/matrixicons.svg#off"></use></svg></div>
          <div class="name" ng-click="sendCmd(light.name, 'ON')">{{light.label}}</div>
        </div>
        <div class="widget" ng-if="(light.type=='Switch' || (light.type==='Group' && light.groupType==='Switch')) && getLightState(light)=='ON'">
          <div class="icon on" ng-click="sendCmd(light.name, 'OFF')"><svg viewBox="0 0 48 48"><use xlink:href="/static/matrix-theme/matrixicons.svg#on"></use></svg></div>
          <div class="name" ng-click="sendCmd(light.name, 'OFF')">{{light.label}}</div>
        </div>
        
        <!-- Dimmer (use proxy switch _sw, otherwise brightness is set to 100) -->
        <div class="widget" ng-if="light.type==='Dimmer' && getLightState(light)==='OFF'">
          <div class="icon off" ng-click="sendCmd(light.name + '_sw', 'ON')"><svg viewBox="0 0 48 48"><use xlink:href="/static/matrix-theme/matrixicons.svg#off"></use></svg></div>
          <div class="name" ng-click="showHueSelect = !showHueSelect; showHueSelect && refreshSlider()">{{light.label}}
            <div class="hueSelect" ng-init="showHueSelect = false" ng-show="showHueSelect">
              <div class="hueSelectlight"></div>
              <div class="hueSelectOptions">
                <div class="slider-wrapper"><widget-slider ng-model="sliderModel"/></div>
              </div>
            </div>
          </div>
        </div>
        <div class="widget" ng-if="light.type==='Dimmer' && getLightState(light)==='ON'">
          <div class="icon on" ng-click="sendCmd(light.name, 'OFF')"><svg viewBox="0 0 48 48"><use xlink:href="/static/matrix-theme/matrixicons.svg#on"></use></svg></div>
          <div class="name" ng-click="showHueSelect = !showHueSelect; showHueSelect && refreshSlider()">{{light.label}}
            <div class="value">{{itemValue(light.name)}} %</div>
            <div class="hueSelect" ng-init="showHueSelect = false" ng-show="showHueSelect">
              <div class="hueSelectlight"></div>
              <div class="hueSelectOptions">
                <div class="slider-wrapper"><widget-slider ng-model="sliderModel"/></div>
              </div>
            </div>
          </div>
        </div>

        <!-- Group Dimmer -->
        <div class="widget" ng-if="light.type==='Group' && light.groupType==='Dimmer' && getLightState(light)==='OFF'" >
          <div class="icon off" ng-click="sendCmd(light.name, 'ON')"><svg viewBox="0 0 48 48"><use xlink:href="/static/matrix-theme/matrixicons.svg#off"></use></svg></div>
          <div class="name" ng-click="showHueSelect = !showHueSelect; showHueSelect && refreshSlider()">{{light.label}}
            <div class="hueSelect" ng-init="showHueSelect = false" ng-show="showHueSelect">
              <div class="hueSelectlight"></div>
              <div class="hueSelectOptions">
                <div class="slider-wrapper"><widget-slider ng-model="sliderModel"/></div>
              </div>
            </div>
          </div>
        </div>
        <div class="widget" ng-if="light.type==='Group' && light.groupType==='Dimmer' && getLightState(light)==='ON'">
          <div class="icon on" ng-click="sendCmd(light.name, 'OFF')"><svg viewBox="0 0 48 48"><use xlink:href="/static/matrix-theme/matrixicons.svg#on"></use></svg></div>
          <div class="name" ng-click="showHueSelect = !showHueSelect; showHueSelect && refreshSlider()">{{light.label}}
            <div class="value">{{itemValue(light.name)*1}} %</div> <!-- *1 fixes 100.00000000 display -->
            <div class="hueSelect" ng-init="showHueSelect = false" ng-show="showHueSelect">
              <div class="hueSelectlight"></div>
              <div class="hueSelectOptions">
                <div class="slider-wrapper"><widget-slider ng-model="sliderModel"/></div>
              </div>
            </div>
          </div>
        </div>

        <!-- Color, Group Color -->
        <div class="widget" ng-if="(light.type=='Color' || (light.type==='Group' && light.groupType==='Color')) && getLightState(light)==='OFF'">
          <div class="icon off" ng-click="sendCmd(light.name, 'ON')"><svg viewBox="0 0 48 48"><use xlink:href="/static/matrix-theme/matrixicons.svg#off"></use></svg></div>
          <div class="name" ng-click="showHueSelect = !showHueSelect; showHueSelect && refreshSlider()">{{light.label}}
            <div class="hue" ng-style="{'background': 'rgb(' + itemValue(light.name + '_rgb') + ')'}"></div>
            <div class="hueSelect" ng-init="showHueSelect = false" ng-show="showHueSelect">
              <div class="hueSelectlight"></div>
              <div class="hueSelectOptions">
                <div class="slider-wrapper"><widget-slider ng-model="sliderModel"/></div>
                <a href="" ng-click="sendCmd(light.name, color.hsb)" ng-repeat="color in hueColors" ng-style="{ 'background': color.hex }"></a>
              </div>
            </div>
          </div>
        </div>
        <div class="widget" ng-if="(light.type=='Color' || (light.type==='Group' && light.groupType==='Color')) && getLightState(light)==='ON' && lightValue(light.name + '_rgb')!='NULL'">
          <div class="icon on" ng-click="sendCmd(light.name, 'OFF')"><svg viewBox="0 0 48 48"><use xlink:href="/static/matrix-theme/matrixicons.svg#on"></use></svg></div>
          <div class="name" ng-click="showHueSelect = !showHueSelect; showHueSelect && refreshSlider()">{{light.label}}
            <div class="hue" ng-style="{'background': 'rgb(' + itemValue(light.name + '_rgb') + ')'}"></div>
            <div class="value">{{itemValue(light.name).split(',')[2]}} %</div>
            <div class="hueSelect" ng-init="showHueSelect = false" ng-show="showHueSelect">
              <div class="hueSelectlight"></div>
              <div class="hueSelectOptions">
                <div class="slider-wrapper"><widget-slider ng-model="sliderModel"/></div>
                <a href="" ng-click="sendCmd(light.name, color.hsb)" ng-repeat="color in hueColors" ng-style="{ 'background': color.hex }"></a>
              </div>
            </div>
          </div>
        </div>

        <!-- Non-initialized lights -->
        <div class="widget" ng-if="getLightState(light)=='NULL'">
          <div class="icon off" ng-click="sendCmd(light.name, 'ON')"><svg viewBox="0 0 48 48"><use xlink:href="/static/matrix-theme/matrixicons.svg#none"></use></svg></div>
          <div class="name" ng-click="sendCmd(light.name, 'ON')">{{light.label}}</div>
        </div>
      </div>
		</div>
	</div>
</div>
</div>

lights.js file (see template for file locations):

(function() {
	"use strict";

	function internalGetLightState(state, name) {
		//window.console.log("Checking state for " + state);
		if (state == null || state === "NULL" || typeof state !== 'string') {
			//window.console.log("Checking state for " + name + ". In: " + state + ", Out: NULL");
			return "NULL";
		} else {
			if (state === "OFF" || // Switch Item
				state === "0" || // Dimmer Item
				state === "0.00000000" || // Group Dimmer Item
				state.split(',')[2] === "0") { // Color Item
				//window.console.log("Checking state for " + name + ". In: " + state + ", Out: OFF");
				return "OFF";
			} else {
				//window.console.log("Checking state for " + name + ". In: " + state + ", Out: ON");
				return "ON";
			}
		}
	}

	angular.module('app', [])
	.filter('lightsOn', function() {
		return function(input) {
			if (input == null) {
				return undefined;
			}
			//input = input || '';
			var onOnly = input.filter(function (entry) {
				return internalGetLightState(entry.state, entry.name) === 'ON';
			});
			return onOnly;
		}
	})
	.controller('lightsController', ['$scope', '$timeout', 'OHService', function($scope, $timeout, OHService) {
		// Function to get the state of a light (Switch, Dimmer, Color) broken down to ON / OFF / NONE.
		$scope.getLightState = function (item) {
			return internalGetLightState(item.state, item.name);
		};

		// Needed to refresh slider after showing parent element (popup)
		$scope.refreshSlider = function () {
			$timeout(function () {
				//$scope.$broadcast('rzSliderForceRender');
				$scope.$emit('openhab-update'); // Seems to do nothing
			});
		};
	}]); 
})();

CSS modifications (append to pride-theme.css):

.slider-wrapper {
	min-width: 265px;
}

.section .sub-title .summary {
	font-size: 14px;
	color: #ffffff;
	opacity: 0.7;
}

.section .widget .name .hue {
	margin-right: 0;
	margin-left: 7px;
}

.section .hueSelect {
	z-index: 1000;
}

.section .hueSelect a {
	width: 25px;
    height: 25px;
}

If you are still looking for a soultion and for other users that may have that problem… these are the code lines that workes for me…

<div class="value">
    <div class="main">{{'%.1f' | sprintf:itemValue('OWMCurrentTemperature').split('.')[0] | number:0}}</div>
    <div class="decimals">.{{'%.1f' | sprintf:itemValue('OWMCurrentTemperature').split('.')[1].substring(0,1) | number:0}}</div>
    <div class="sub">&#176C</div>
</div>

and this is the result:
2020-04-26 20_01_39-HABPanel

EDIT:
This works aswell:

<div class="value">
    <div class="main">{{itemValue('OWMCurrentTemperature').split('.')[0] | number:0}}</div>
    <div class="decimals">.{{itemValue('OWMCurrentTemperature').split('.')[1].substring(0,1) | number:0}}</div>
    <div class="sub">&#176C</div>
</div>

I use

  <div class="main">{{itemValue('Outside_ds18b20_temperature') - 0.5 | number:0}}</div>
  <div class="decimals">.{{(itemValue('Outside_ds18b20_temperature') * 10 % 10 | number:0)}}</div>
  <div class="sub">&#176C</div>

No string manipulations involved … Many ways to solve same problem :slight_smile:

1 Like

Hey @crnjan ,

i really like your solution! Today i played a bit with the chart widget code… and have a strange problem…

The chart is working in generell but gets unlimited resized in height every X seconds/milliseconds :face_with_monocle:

is it still working for you? Did you some other modifications to the CSS file? Do you mind sharing your full Panel code?

this is the code i’m using in HABPanel

    <div class="graph">
        <div ng-init='model_nik={
            "type": "chart",
            "charttype": "interactive",
            "service": "influxdb",
            "period": "D",
            "axis": {
                "y": { "ticks": 5 },
                "y2": { "enabled": true },
            },
            "series": [
            {
                "axis": "y",
                "display_line": true,
                "display_area": false,
                "item": "OWMCurrentTemperature",
                "name": "Temperature",
                "color": "var(--pride-2-color)"
            },
            {
                "axis": "y2",
                "display_line": true,
                "display_area": true,
                "item": "OWMCurrentHumidity",
                "name": "Humidity",
                "color": "#2389da"
            }
            ]
        }'>

        <div class="widget-chart-container">
            <widget-chart ng-model="model_nik"></widget-chart>          
        </div>
        </div>
    </div>

Its just not working if I add this code to a custom widget… the default chart widget is working… but i need the chart in the custom widget… maybe @ysc have a hint too?

I’m running on openhabian openHAB 2.5.4-1 (Release Build)

Thanks
/Holger

Hey! Yes, forgot to add changes I did in the css file, I edited my original post and included the changes there, please let me know if it helps …

1 Like

awesome… that was the trick… Thank you :slight_smile:

Hi Eikowagenknecht,

Thank you, it worked like a charm! I wish i could by you a beer :slight_smile:

Best regards,
Simon

Hey Simon,

I’m glad it works :slight_smile: If you really want to express your thanks financially, the openHAB foundation always welcomes donations: https://www.openhab.org/about/donate.html

Eiko

1 Like

Hi, I still have this resizing issue after applying your changes. Would it be possible to post (attach) your complete css file ?

Thanks

Attached to my original post, please let me know if it works for you.

Yes, thanks. Issue was my browser cache, needed to empty it.