Design your SVG floorplan or dashboard for HABPanel with Inkscape

Yes, you can assign values to scope variables on the fly with ng-click, for instance:

  • showOverlay=true
  • showOverlay=!showOverlay (toggle)

Then you can use ng-if, ng-show and even ng-class or ng-style on the overlay using this variable. All these are valid:

  • ng-if="showOverlay"
  • ng-show="showOverlay"
  • ng-class="{ hidden: !showOverlay }" (with an associated 'hidden' CSS class)
  • ng-style="{ visibility: showOverlay ? 'visible' : 'hidden' }"

SVG is a Document Object Model much like HTML, therefore all of AngularJS’ directives that aren’t designed to work with specific HTML elements will work on SVG elements as well.

3 Likes

I tried to place some elements for blind control … Up, Stop, Down…
However the whole SVG is too crowded and I would rather use a Slider for this.
Can a slider be used in the SVG?
Thanks!

Current:
image

Would like to:
maybe a slider like this… which could replace the “window” itself and could control the blind and the same time show the current %state

image

This is just plain awesome! I have a question about having an item react to an update from OpenHAB. For example, I have door sensors on all exterior doors, is there a way that I can make the object for my doors fill red when the door is opened?
I created a “ng-class” attribute for:

{"door-open": itemState('ContactOfficeDoor') == 'ON' }

I added this to my css file:

.door-open {
        fill: #ff0000 !important;
}

When I open the door, the panel does not change… I did not create an ng-click for a send command, because I don’t want to be able to click on the door and turn the sensor on, I would prefer it to react from an update from the device itself. Is this possible?

@jsable This is perfectly possible and your css and ng-class looks good already.

Maybe, you have a svg group selected instead of only one specific element?! If so, then you can simply assign ng-class to all of the grouped elements and it should work.

1 Like

@Simson,

Thanks for the encouragement! I figured it out, forgot I had a translation set, so the ‘ON’ didn’t work for me, had to change it to ‘is Open’ and they all started glowing red like I wanted!

Quick tip from HABPanel Development & Advanced Features: Start Here!

itemState(itemname, [ignoreTransform]): retrieves the state of an item by its name;
ignoreTransform (optional, false by default) will return the raw state (e.g. ‘CLOSED’) instead of the transformed state (‘zu’)

So if you have transformations you can explicitely ignore them:
itemState('ContactOfficeDoor', true) == 'ON'
(note the “true” as 2nd argument)

1 Like

I’m a little stuck and I’m hoping you can point out what mistake I’m making. I created the .css file just as shown above and I created a really simple file:

I put both files in the HTML folder and when I go to 192.168.1.151:8080/static/Test.svg it shows up but when I add it to HABPanel all I get is this:
image

Is there something I’m missing? Any pointers are appreciated.

Thanks!

Can you show the code you put in the template widget? Is there an error something showing in the developer tools console? (F12, Console tab, refresh the page)

Here’s the code from the widget:

<div oc-lazy-load="'/static/Test.css'">
	<div ng-include="'/static/Test.svg'"></div>
</div>

In the console the only thing I get that is somewhat suspicious is this:

Service worker not registered 
SecurityError: Only secure origins are allowed

but that’s all I see. Otherwise I have a default widget controlling a switch on the dashboard and it works just fine.

This is how I have the svg configured in Inkscape:

and this is the file it exports:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->

<svg:svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   width="500"
   height="500"
   viewBox="0 0 132.29166 132.29167"
   version="1.1"
   id="svg3741"
   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
   sodipodi:docname="Test.svg">
  <svg:defs
     id="defs3735" />
  <sodipodi:namedview
     id="base"
     pagecolor="#ffffff"
     bordercolor="#666666"
     borderopacity="1.0"
     inkscape:pageopacity="0.0"
     inkscape:pageshadow="2"
     inkscape:zoom="0.35"
     inkscape:cx="155.08602"
     inkscape:cy="535.71429"
     inkscape:document-units="mm"
     inkscape:current-layer="svg3741"
     showgrid="false"
     inkscape:window-width="944"
     inkscape:window-height="1002"
     inkscape:window-x="960"
     inkscape:window-y="0"
     inkscape:window-maximized="0"
     units="px" />
  <svg:metadata
     id="metadata3738">
    <rdf:RDF>
      <cc:Work
         rdf:about="">
        <dc:format>image/svg+xml</dc:format>
        <dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
        <dc:title></dc:title>
      </cc:Work>
    </rdf:RDF>
  </svg:metadata>
  <svg:g
     inkscape:label="Layer 1"
     inkscape:groupmode="layer"
     id="layer1"
     transform="translate(0,-164.70832)"
     ng-class="{&quot;light-on&quot;: itemState('KitchenCeilingLights') == 'ON' }"
     ng-click="sendCmd('KitchenCeilingLights', (itemState('KitchenCeilingLights') == 'ON') ? 'OFF' : 'ON')"
     cursor="pointer">
    <svg:rect
       id="rect3743"
       width="123.22024"
       height="127.75595"
       x="4.5357156"
       y="167.73215"
       style="stroke-width:0.26458332" />
  </svg:g>
  
</svg:svg>

I am using Inkscape 0.92 if that makes any difference, and OH 2.2 stable.

1 Like

Well, I don’t know what to say, I initially had the same problem as you with the SVG you provided.
So I loaded it in my Inkscape, removed the “metadata” node by clicking on it and pressing the image button in the XML editor, and it gave me this, which works:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->

<svg
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   width="500"
   height="500"
   viewBox="0 0 132.29166 132.29167"
   version="1.1"
   id="svg3741"
   inkscape:version="0.92.1 r15371"
   sodipodi:docname="Test.svg">
  <defs
     id="defs3735" />
  <sodipodi:namedview
     id="base"
     pagecolor="#ffffff"
     bordercolor="#666666"
     borderopacity="1.0"
     inkscape:pageopacity="0.0"
     inkscape:pageshadow="2"
     inkscape:zoom="0.35"
     inkscape:cx="-1312.0568"
     inkscape:cy="535.71429"
     inkscape:document-units="mm"
     inkscape:current-layer="svg3741"
     showgrid="false"
     inkscape:window-width="1920"
     inkscape:window-height="1017"
     inkscape:window-x="-8"
     inkscape:window-y="-8"
     inkscape:window-maximized="1"
     units="px" />
  <g
     inkscape:label="Layer 1"
     inkscape:groupmode="layer"
     id="layer1"
     transform="translate(0,-164.70832)"
     ng-class="{'light-on': itemState('KitchenCeilingLights') == 'ON' }"
     ng-click="sendCmd('KitchenCeilingLights', (itemState('KitchenCeilingLights') == 'ON') ? 'OFF' : 'ON')"
     cursor="pointer">
    <rect
       id="rect3743"
       width="123.22024"
       height="127.75595"
       x="4.5357156"
       y="167.73215"
       style="stroke-width:0.26458332" />
  </g>
</svg>

Note how it removed the svg: namespace prefixes in elements and added it as the default namespace (xmlns="http://www.w3.org/2000/svg"). I have an older Inkscape version than you but I don’t think it matters. Very odd.

Another thing: do not use double quotes in attribute values as it will apparently replace them by &quot; and that won’t work. See &quot;light-on&quot; which I replaced by 'light-on'.

1 Like

I just followed the same steps you did and it fixed the issue here too. There may have been a change in the way the Inkscape application handles the SVG generation. I followed your steps above exactly and that’s the file it generated for me. So my guess is there’s something in the way the SVG is being generated by the program, maybe something in the way they handle the metadata.

I don’t know but deleting the metadata fixed the issue.

1 Like

Your floor plan looks stunning.

Did you create your floor plan with Inkscape ?

@ysc,

Why don’t we add support for Floor plan in Habpanel as they did for Home assistance ?

3 Likes

Thank you :blush:
No, I did any creative work like floorplan painting, text and font design etc. in Affinity Designer (I am a big fan of that tool!).
Exported as SVG. Any additional work and duplicating buttons and texts is done in Inkscape (which is not so funny at least on the Mac) :slight_smile:

1 Like

@ysc
A bit similar to what @shorty707 was asking:
How could I add a slider like that http://angular-slider.github.io/angularjs-slider/ to my floorplan controlling light percentage or blind control?

This is all awesome and I’ve already created some genius stuff. Now, I’m facing a problem and maybe you have an idea what is wrong…
To indicate an open door I’d like to change the color (which works) then adjust the X,Y position (which works), and then rotate it by 45 degree… which doesn’t work.
I attached a ng-class attribute to the door object

{"tuer-balkon-offen": itemState('Fenster_EG_Kueche') == '0' }

This is my class:

.tuer-balkon-offen { 
        fill:#ff0000 !important;
        x:-105  !important; 
        y:225   !important;
        transform:rotate(-45.0) !important;         <---- what is wrong here?
}

Do you know why “transform:rotate” doesn’t work? … all other attributes are fine. I tried different formats as well like this one…: transform=“rotate(-45)”

Try to define the animation as a keyframe:

@-webkit-keyframes rotate {
100% { transform: rotate(-45deg); }
}

and use

.tuer-balkon-offen { 
   transform-origin: top right !important;
   animation: rotate 2s forwards !important;
}

I have follow this great tutorial to make my own floorplan. It works great on computer displaying fullscreen 1920x1080 size floorplan. But on android tablet and cell phone, the svg was displayed 2-3 times larger. (I am sure my tablet and phones were 1920x1080 screens). How can I make it adapt to android browsers? Is there something im missing?

Thank you very much.

@Simson,

it works in general! So many thanks for the first hint.
However, the challenge is now that the object does not rotate around “top right”, but around 0,0 point of the SVG canvas.
So “transform-origin” seems not to work
Thanks
Pirx

@illxi
try this one: open the SVG file and change the width and height to:

   width="100%"
   height="100%"