Design your SVG floorplan or dashboard for HABPanel with Inkscape

floorplan
svg
inkscape
Tags: #<Tag:0x00007f6cf1200688> #<Tag:0x00007f6cf12003b8> #<Tag:0x00007f6cf1200070>

(Yannick Schaus) #21

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)


(Matthew L Adams) #22

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.


(Yannick Schaus) #23

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'.


(Matthew L Adams) #24

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.


(Kiran Patil) #25

Your floor plan looks stunning.

Did you create your floor plan with Inkscape ?


(Kiran Patil) #26

@ysc,

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


(Joerg) #27

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:


(Joerg) #28

@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?


(Maciej Berghof) #29

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)”


( ) #30

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;
}

(Sam) #31

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.


(Maciej Berghof) #32

@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


(Maciej Berghof) #33

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

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

(Sam) #34

It works! Thank you very much!


( ) #35

I read about this strange behavior in the linked HomeAssistant thread. It might help to just redraw your rectangles and try again.

“transform-origin” should generally work - at least it does in my case.


(Maciej Berghof) #36

I did many tests with “transform-origin”. It does work, but you need to specify the exact position within the SVG canvas.
In example. This is the object (let say it is a door) to be rotated

  <rect 
     ng-class="{&quot;tuer-balkon-offen&quot;: itemState('Door_status') == 'ON' }"
     style="fill:url(#linearGradient10225);fill-opacity:1;fill-rule:nonzero;stroke:#808080;stroke-width:0.23461722;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
     id="door"
     x="210"
     y="175"
     width="42"
     height="5" />

The rotation in CSS must be defined like this

@-webkit-keyframes rotate {  
100% { transform: rotate(-60deg)  !important}
}

@keyframes rotate {
100% { transform: rotate(-60deg) !important}
}

.tuer-balkon-offen {
   transform-origin: 210px 175px !important;
   animation: rotate 2s linear !important;
}

A “transform-origit: top left” will point to the position in the canvas which results of a wired rotation of the door.
The downside of the px-notation is that I will need to define every single door in CSS and whenever I change the postion of a door in the SVG I need to update the CSS file. If someone knows how to avoid it, raise your hand please :slight_smile:


(Yannick Schaus) #37

There’s a well written article about transform origins in SVG here, maybe it’ll help:


(Maciej Berghof) #38

Thanks Yannick,

I found this article already yesterday. It is a very good peace of work but unfortunately there is no answer to my problem.

Regards
Pirx


(Dome) #39

This is just unbelievable. Here’s my very rough progress so far.

One question I have: Is there any way to have multiple use cases in an “ng-class” attribute?

Let’s say I have a String item with three possible states, and I’d like to define three different ng-class sets. Is it possible to define something like this (I’ve tried this a few ways with no results):

{"fill-red": itemState('Item_Name') == 'State1' }
{"fill-blue": itemState('Item_Name') == 'State2' }
{"fill-green": itemState('Item_Name') == 'State3' }