Custom Theme in HabPanel 2.1 Example

skin
theme
stylesheet
Tags: #<Tag:0x00007f6ce4fb7720> #<Tag:0x00007f6ce4fb75b8> #<Tag:0x00007f6ce4fb7478>

(Michael Stjerna) #203

@pmpkk

I got it to work now, found an easy way
Patrick, can you please put this into your documentation:

You need to “persist” the OpenHAB values and restore them when restarting the system.
If you don’t have a solution in place you can simply add the “MapDB Persistence” from the PaperUI -> AddOns --> PERSISTENCE.

You need to create a file that stores all the vaiables into the MapDB. You will only store values that are updated and ONLY the latest value.

Create the file:
/etc/openhab2/persistence/mapdb.persist

Strategies {
    default = everyUpdate
}

Items {
    // persist all Items on every change and restore them from the MapDB at startup
    * : strategy = everyChange, restoreOnStartup
}

//Michael Stjerna


(Unparagoned) #204

Just make a widget with a frame pointed to the authorisation html. So you can access it from habpannel. I’ve also got another panel that displays and and deletes all the auth ids so you can start from a fresh start if needed.

Cross post:

I thought I’ll share a picture of my customised version of Patric’s awesome skin and spotify api’s.


(Michael Stjerna) #205

Nice one.
Would you like to share it? I would like to “copy” the playlist dropdown :slight_smile:
Did you or anyone else manage to get he suggested Angular update from the page containing the player? My solution with a forced update from the script file wasn’t a clean solution. Hammering the spotify API every 5sek 24/7/365 isn’t that good …

Keep up the good work everyone!
And again @pmpkk thanks for all your contributions on the HABPanel layouts.

//Michael


(Unparagoned) #206

Here is the section from the widget

    <div class="widget" >
      <div class="icon off" ng-click="sendCmd('spotify_proxy_update', 'ON')"><svg viewBox="0 0 48 48"><use xlink:href="/static/matrix-theme/squidink.svg#double-arrow"></use></svg></div>
      <div class="nameGroup"><div class="name">Devices</div></div>
      <div class="btn-group" dropdown-append-to-body="true" uib-dropdown>            
        <button id="single-button" type="button" class="btn btn-primary" uib-dropdown-toggle>
          {{itemValue('spotify_current_device')}} <span class="caret"></span>
        </button>
        <ul class="dropdown-menu"  uib-dropdown-menu role="menu" aria-labelledby="single-button">
          <div ng-init="devices=itemValue('spotify_devices')"></div>
          <div ng-repeat="item in $eval(devices).devices" ng-if="item.state!='NULL'">
            <li role="menuitem"><a ng-click='sendCmd("spotify_action", "play \"" + item.id + "\"")'>{{item.name}}</a></li>
          </div>
        </ul>
      </div>
    </div>

    <div class="widget">
      <div class="icon off" ng-click="sendCmd('spotify_action', 'playlists')"><svg viewBox="0 0 48 48"><use xlink:href="/static/matrix-theme/squidink.svg#double-arrow"></use></svg></div>
      <div class="nameGroup"><div class="name">Play Lists </div></div>
      <div class="btn-group" dropdown-append-to-body="true" uib-dropdown>            
        <button id="single-button" type="button" class="btn btn-primary" uib-dropdown-toggle>
          Select <span class="caret"></span>
        </button>
        <ul class="dropdown-menu" uib-dropdown-menu role="menu" style="overflow: auto; max-height:300px; overflow-x:hidden" aria-labelledby="single-button">
          <div ng-init="playlists=itemValue('spotify_playlists')"></div>
          <div ng-repeat="item in $eval(playlists).items" ng-if="item.state!='NULL'">
            <li role="menuitem"><a ng-click='sendCmd("spotify_action", "play \"" + item.uri + "\"")'>{{item.name}}</a></li>
          </div>         
        </ul>
      </div>
    </div>

Part of it relies on the css file. I’ve never modified a css file before, so I missed it up completely, so some of the other menus look a bit messed up but usable. Items, functions, etc should all be here https://github.com/unparagoned/openhab_spotify-webconnect-api


(Michael Stjerna) #207

Hi @ysc @pmpkk

I do the update within the spotify.rules file instead. On my panel i have an Item that i use to navigate between tabs, when it’s showing the spotify page i let the rule hammer the spotify every 5-sec for an update…
The rules file also updates the list of devices every hour…

//Update the device list 5min after each hour
rule "Spotify update devices"
when
      Time cron "5 * * * * ?"
                then
                        val resp =  executeCommandLine("/usr/bin/python /etc/openhab2/scripts/spotify.py get_devices", 5000)
                        logInfo("Spotify", resp)
end


rule "Spotify run script when page music"
when
      Time cron "0/5 * * * * ?"
                then
                if (MENU_page.state.toString == "P-Music?kiosk=on"){
                        val resp =  executeCommandLine("/usr/bin/python /etc/openhab2/scripts/spotify.py", 5000)
                        logInfo("Spotify", resp)
                }
end

(Patrick) #208

Cool!


(Alexandre) #209

Hi,

For some days I’m trying to fix a bug I have. When a light switch from OFF to ON, I would like to display inside the slider I’ve made the current brightness value. Thing is that I’m unable to make it work :

<div ng-init="slider = { value: itemValue(item.name), options: { floor: 0, ceil: 100, step: 1, showSelectionBar: true } };"></div>

With this code I’m getting “NaN” instead of the item value. I tried to fix a value and it’s working :

<div ng-init="slider = { value: 24, options: { floor: 0, ceil: 100, step: 1, showSelectionBar: true } };"></div>

I tried “{{itemValue(item.name)}}” but it’s definitely not working. May someone know how to use itemValue inside a ng-init ?

Also @pmpkk I would like to make something like a digipad (for a remote channel for examaple), do you ever managed to do somehting like this with your theme ? I didn’t tested yet but I’m not sure it could be easily doable with my current CSS knowledge. I though to use div class=row to arrange the whole thing.

Regards,


(Lorenzo Giordano) #210

I am not sure but if you are using the widget-slider, you should use

item: "item.name" 

instead of value and that’s all I think

Regards


(Alexandre) #211

Hi,

Thank you for your help, I managed to use widget-slider but I’m having an issue with it (the same that I had on another project).

The actual value is correctly displayed on start but the slider position is fixed on the left :

In this picture, you can see “Entrée (debug : value : 69)” and its bar which is using widget-slider thanks to your response, and “Chambre (debug: value : 64)” which use my code.

I have to precise a bit my code :
When “light” is off : value forced to 0
When “light” is on : value should be the actual one right after its turned on.

With your code or mine, it’s working as soon as you set a value using the slider bar, but not when using “ON” button.

I’m still looking for a way to fix it, but once more, thank you :slight_smile:


(Lorenzo Giordano) #212

Hi, why don’t use a simple ng-if and set value:0 when the item is off.
Regards
Lorenzo


(Alexandre) #213

Hi,

This is what I’m actually doing, based on pmpkk work (this code concern only white bulbs) :

    <div class="widget" ng-if="((item.type=='Dimmer' && (itemValue(item.name)=='0' || itemValue(item.name)=='OFF')) || (item.type=='Group' && (itemValue(item.name)=='OFF' || itemValue(item.name)=='NULL'))) && itemValue(item.name + '_color')=='N/A'">
      <div class="icon off" ng-click="sendCmd(item.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">
        <div class="hue" ng-style="{'background': 'rgb(' + itemValue(item.name + '_color') + ')'}"></div>
        <div class="hueSelect" ng-init="showHueSelect = false" ng-show="showHueSelect"><div class="hueSelectItem"></div>
          <div class="hueSelectOptions">
            <!-- Brightness slider bar -->
            <div ng-init="slider = { value: 0, options: { floor: 0, ceil: 100, step: 1, showSelectionBar: true } };"></div>
            <rzslider rz-slider-model="slider.value" rz-slider-options="slider.options" ng-click="sendCmd(item.name, slider.value)"></rzslider>
          </div>
        </div>
        {{item.label}}
      </div>
    </div>

    <div class="widget" ng-if="((item.type=='Dimmer' && itemValue(item.name)>'0') || (item.type=='Group' && itemValue(item.name)=='ON')) && itemValue(item.name + '_color')=='N/A'">
      <div class="icon on" ng-click="sendCmd(item.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">
        <div class="hue" ng-style="{'background': 'rgb(' + itemValue(item.name + '_color') + ')'}"></div>
        <div class="hueSelect" ng-init="showHueSelect = false" ng-show="showHueSelect"><div class="hueSelectItem"></div>
          <div class="hueSelectOptions">
            <div ng-init='model={"item": item.name, "floor": 0, "ceil": 100, "step":1}'>
              <widget-slider ng-model="model" />
            </div>          
          </div>
        </div>
        {{item.label}} (Debug : value : {{itemValue(item.name)}})
      </div>
    </div>

I don’t have issue when the light is in “OFF” state. Only when a light switch from “OFF” to “ON”.


(Alexandre) #214

I managed to make a digipad :
image

I have to fix the last line using offsets in order to allow a “0” centered without anything else. Here is the code :

    <div class="widget" ng-class="{true: 'disabled'}[itemValue('YamahaReceiverRXV477_InputSource')!='HDMI1' || itemValue('gTeleAmp')=='OFF']">
      <div class="icon off"><svg viewBox="0 0 48 48"><use xlink:href="/static/matrix-theme/squidink.svg#flat-tv"></use></svg></div>
      <div class="name">Channel</div>
      <div class="controlGroup">

        <div class="row">
          <div class="col-md-12">
            <div class="control" ng-click="sendCmd('LG_TV0_ChannelUp', 'ON')">1</div>
            <div class="control" ng-click="sendCmd('LG_TV0_ChannelUp', 'ON')">2</div>
            <div class="control" ng-click="sendCmd('LG_TV0_ChannelUp', 'ON')">3</div>
          </div>
        </div>

        <div class="row">
          <div class="col-md-12">
            <div class="control" ng-click="sendCmd('LG_TV0_ChannelUp', 'ON')">4</div>
            <div class="control" ng-click="sendCmd('LG_TV0_ChannelUp', 'ON')">5</div>
            <div class="control" ng-click="sendCmd('LG_TV0_ChannelUp', 'ON')">6</div>
          </div>
        </div>

        <div class="row">
          <div class="col-md-12">
            <div class="control" ng-click="sendCmd('LG_TV0_ChannelUp', 'ON')">7</div>
            <div class="control" ng-click="sendCmd('LG_TV0_ChannelUp', 'ON')">8</div>
            <div class="control" ng-click="sendCmd('LG_TV0_ChannelUp', 'ON')">9</div>
          </div>
        </div>

        <div class="row">
          <div class="col-md-12">
            <div class="control" ng-click="sendCmd('LG_TV0_ChannelUp', 'ON')"><svg viewBox="0 0 80 80"><use xlink:href="/static/matrix-theme/squidink.svg#top-arrow-2"></use></svg></div>
            <div class="control" ng-click="sendCmd('LG_TV0_ChannelUp', 'ON')">0</div>
            <div class="control" ng-click="sendCmd('LG_TV0_ChannelDown', 'ON')"><svg viewBox="0 0 80 80"><use xlink:href="/static/matrix-theme/squidink.svg#down-arrow-2"></use></svg></div>
          </div>
        </div>
        
      </div>
    </div>

(Patrick) #215

this looks cool!

All the buttons are wired up to “channel up”, so I don’t understand how it works …


(Alexandre) #216

It was just a test code, I didn’t implemented function behind yet.


(Michael Stjerna) #217

Nice one, I Will take this idea :slight_smile:


(Yannick Schaus) #218

FYI - this could be interesting for you extreme customizers :grin:


(Michael Stjerna) #219

Hi

@pmpkk @ysc thanks for all your help and examples.
Here are some screenshots of my panel. There are still some work to be done. I just bought a NetAtmo Weather station and a WelcomeHome Camera that needs to be implemented :slight_smile:
I need to tweak the thermostat control, it looks terrible right now. I needed it up fast since I have this installation at my summerhouse and need to turn on the heating remote when I plan to go there (Getting cold in Sweden)


(Andrew Pawelski) #220

Are those icons in the top right buttons to other panels?
Could you share the code for these either way


(Michael Stjerna) #221

@Andrew_Pawelski

Yes I use them to navigate, create a custom String-item to save the navigation

The first section is the clock (NTP), and 3 group items to show number of lights, windows, doors open.and then the navigation.
You can remove the “?kiosk” if you don’t want it to run in full-screen.


<div class="section">
	<div class="controls">

		<div class="widgetMenu">
			<div class="col1">
				<div class="name">System</div>
			</div>
			<div class="col2">
				<div class="icon off"><svg viewBox="0 0 48 48"><use xlink:href="/static/matrix-theme/squidink.svg#round-clock"></use></svg></div>
				<div class="name">{{itemValue('NTPServer_Date') | date:'HH:mm'}}</div>
			</div>
		</div>
		
		
		<div class="widgetMenu2">
			<div class="col2">
				<div class="icon off"><svg viewBox="0 0 48 48"><use xlink:href="/static/matrix-theme/squidink.svg#light_bulb"></use></svg></div>
				<div class="name">{{itemValue('gLandetLightON')}} / 6</div>
			</div>
			<div class="col2">
				<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">{{itemValue('gLandetWindowOpen')}} / 4</div>
			</div>
			<div class="col2">
				<div class="icon off"><svg viewBox="0 0 48 48"><use xlink:href="/static/matrix-theme/squidink.svg#door-2"></use></svg></div>
				<div class="name">{{itemValue('gLandetDoorOpen')}} / 5</div>
			</div>			
		</div>
    


		<div class="widget.wide">
			<div class="controlGroup">
				<div class="control" ng-class="{true: 'on'}[itemValue('MENU_page')=='P-System?kiosk=on']" ng-click="sendCmd('MENU_page', 'P-System?kiosk=on')"><svg viewBox="0 0 80 80"><use xlink:href="/static/matrix-theme/squidink.svg#drive"></use></svg></div>
				<div class="control" ng-class="{true: 'on'}[itemValue('MENU_page')=='P-Calendar?kiosk=on']" ng-click="sendCmd('MENU_page', 'P-Calendar?kiosk=on')"><svg viewBox="0 0 80 80"><use xlink:href="/static/matrix-theme/squidink.svg#calendar"></use></svg></div>
				<div class="control" ng-class="{true: 'on'}[itemValue('MENU_page')=='P-Wifi?kiosk=on']" ng-click="sendCmd('MENU_page', 'P-Wifi?kiosk=on')"><svg viewBox="0 0 80 80"><use xlink:href="/static/matrix-theme/squidink.svg#home-adaptor"></use></svg></div>
				<div class="control" ng-class="{true: 'on'}[itemValue('MENU_page')=='P-Music?kiosk=on']" ng-click="sendCmd('MENU_page', 'P-Music?kiosk=on')"><svg viewBox="0 0 80 80"><use xlink:href="/static/matrix-theme/squidink.svg#sound2"></use></svg></div>
				<div class="control" ng-class="{true: 'on'}[itemValue('MENU_page')=='P-HomeControl?kiosk=on']" ng-click="sendCmd('MENU_page', 'P-HomeControl?kiosk=on')"><svg viewBox="0 0 80 80"><use xlink:href="/static/matrix-theme/squidink.svg#home-2"></use></svg></div>
				<div class="control" ng-class="{true: 'on'}[itemValue('MENU_page')=='P-ESP?kiosk=on']" ng-click="sendCmd('MENU_page', 'P-ESP?kiosk=on')"><svg viewBox="0 0 80 80"><use xlink:href="/static/matrix-theme/squidink.svg#thermometer-3"></use></svg></div>
				<div class="control" ng-class="{true: 'on'}[itemValue('MENU_page')=='P-Weather?kiosk=on']" ng-click="sendCmd('MENU_page', 'P-Weather?kiosk=on')"><svg viewBox="0 0 80 80"><use xlink:href="/static/matrix-theme/squidink.svg#sunset"></use></svg></div>
			</div>		
		</div>

   
	</div>

</div>










(Andrew Pawelski) #222

I understand how to change dashboards, more interested in the layout and where it is.
is that different to how @ysc has done it here?

New display options (incl. experimental custom widgets everywhere!)