Hi folks,
A HAPPY NEW YEAR to the entire community!!
While the wife and kids were still sleeping, I sneaked downstairs to experiment with light sources in SVG. Not sure whether this is called dedication, or just me being pathetic
With this simple flow:
[{"id":"4a7aaca8.bd6084","type":"ui_svg_graphics","z":"7f1827bd.8acfe8","group":"7185c2fb.c66bbc","order":0,"width":"12","height":"12","svgString":"<div class=\"contain-demo\"> \n <svg width=\"100%\" height=\"100%\" viewBox=\"0 0 250 250\" enable-background=\"new 0 0 250 250\">\n <defs>\n <!--The default filter region is x=-10% y=-10% width=120% height=120%-->\n <!--Which need to be shrinked to clip the filter at the room boundaries-->\n <filter id=\"green_light\" x=\"0%\" y=\"0%\" width=\"100%\" height=\"100%\">\n <feGaussianBlur in = \"SourceAlpha\" stdDeviation=\"1\" result=\"blur1\" />\n <feSpecularLighting result=\"specOut\" in=\"blur1\" specularExponent=\"30\" lighting-color=\"#00cc00\" >\n <fePointLight x=\"141\" y=\"73\" z=\"80\" />\n </feSpecularLighting>\n </filter>\n </defs>\n \n <image width=\"100%\" height=\"100%\" id=\"background\" xlink:href=\"https://www.roomsketcher.com/wp-content/uploads/2016/10/1-Bedroom-Floor-Plans.jpg\" />\n\n <rect id=\"rect_living\" x=\"80\" y=\"30\" width=\"123\" height=\"86\" fill=\"black\" fill-opacity=\"0.1\" filter=\"\"/>\n <text id=\"light_living\" x=\"141\" y=\"73\" font-family=\"FontAwesome\" fill=\"green\" stroke=\"darkgreen\" font-size=\"25\" text-anchor=\"middle\" alignment-baseline=\"middle\" stroke-width=\"1\">fa-lightbulb-o</text>\n </svg>\n</div>","clickableShapes":[{"targetId":"#light_living","action":"click","payload":"light_living","payloadType":"str","topic":"light_living"}],"javascriptHandlers":[],"smilAnimations":[],"bindings":[],"showCoordinates":false,"autoFormatAfterEdit":false,"showBrowserErrors":true,"showBrowserEvents":false,"enableJsDebugging":false,"sendMsgWhenLoaded":false,"outputField":"payload","editorUrl":"//drawsvg.org/drawsvg.html","directory":"","panning":"disabled","zooming":"disabled","panOnlyWhenZoomed":false,"doubleClickZoomEnabled":false,"mouseWheelZoomEnabled":false,"dblClickZoomPercentage":150,"name":"","x":680,"y":2400,"wires":[["e4f8bd1d.95b4a"]]},{"id":"e4f8bd1d.95b4a","type":"link out","z":"7f1827bd.8acfe8","name":"SVG output msg","links":["b5e846dd.ae7e88"],"x":815,"y":2400,"wires":[]},{"id":"b5e846dd.ae7e88","type":"link in","z":"7f1827bd.8acfe8","name":"","links":["e4f8bd1d.95b4a"],"x":95,"y":2400,"wires":[["9327a30d.6d2f2"]]},{"id":"6000cdf2.42d564","type":"change","z":"7f1827bd.8acfe8","name":"Update filter attribute","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\t\"command\": \"set_attribute\",\t\"selector\": \"#rect_living\",\t\"attributeName\": \"filter\",\t\"attributeValue\": payload\t} ","tot":"jsonata"},{"t":"delete","p":"topic","pt":"msg"},{"t":"delete","p":"event","pt":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":460,"y":2400,"wires":[["4a7aaca8.bd6084"]]},{"id":"9327a30d.6d2f2","type":"function","z":"7f1827bd.8acfe8","name":"Toggle light state","func":"if (msg.topic === \"light_living\") {\n var state = flow.get(\"state_light\");\n \n node.error(\"old state = \" + state );\n \n if (state === \"ON\") {\n state = \"OFF\";\n msg.payload = \"\";\n }\n else {\n state = \"ON\";\n msg.payload = \"url(#green_light)\";\n }\n \n node.error(\"new state = \" + state );\n \n flow.set(\"state_light\", state);\n}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":230,"y":2400,"wires":[["6000cdf2.42d564"]]},{"id":"7185c2fb.c66bbc","type":"ui_group","z":"","name":"SVG light demo","tab":"35f53152.449cde","order":2,"disp":true,"width":"12","collapse":false},{"id":"35f53152.449cde","type":"ui_tab","z":"","name":"Lights","icon":"dashboard","disabled":false,"hidden":false}]
I can show visually which light is ON on my floorplan. I this demo I have used a green LED light:
I'm not an SVG expert at all, but would like to spread some basic ideas of the SVG possibilities...
If anybody has a better implementation, please share it with us!!!
In SVG you can define a light source element of different types:
- feDistantLight defines a distant light source, similar to how the sun lights everything during the day.
- fePointLight defines a light source that radiates from a single point, similar to how a light bulb lights a room.
- feSpotLight defines a light source similar to a spot light that shines intensely over a small area.
So I think that for my home automation the fePointLight seems to be the best match to simulate a light bulb.
Then we need to create a filter chain, where the result of a filter will be the input of the next filter.
This is my chain after a bit of trial and error:
<filter id="green_light" x="0%" y="0%" width="100%" height="100%">
<feGaussianBlur in = "SourceAlpha" stdDeviation="1" result="blur1" />
<feSpecularLighting result="specOut" in="blur1" specularExponent="30" lighting-color="#00cc00" >
<fePointLight x="141" y="73" z="80" />
</feSpecularLighting>
</filter>
</defs>
Some details about this:
-
I positioned the light in the middle of my room. Don't know if I can make this relative to the room, because now it is relative to the origin of the SVG, which causes the definition not being reusable for my other rooms...
-
I used feSpecularLighting to apply a colour to my light. In this case I have specified GREEN ("#00cc00").
-
The feGaussianBlur applies some blur.
-
It is important to specify a filter region (x="0%" y="0%" width="100%" height="100%") because the default region (x="-10%" y="-10%" width="120%" height="120%") would cause the filter to be applied also around our room (rectangle):
Since the demo floorplan is a simple image of a floorplan, the light would shine across multiple rooms (not taking into account the walls). To solve that we draw a rectangle above the room contour, and apply the light filter only to that rectangle:
<image width="100%" height="100%" id="background" xlink:href="https://www.roomsketcher.com/wp-content/uploads/2016/10/1-Bedroom-Floor-Plans.jpg" />
<rect id="rect_living" x="80" y="30" width="123" height="86" fill="black" fill-opacity="0.1" filter=""/>
Some details about this:
- By default I apply an empty filter (i.e. no filter) to this rectangle, because the light is OFF when we start.
- I set the color to black and opacity to
0.1
to make the room a bit darker (since the light is off by default):
And then in the flow I apply the filter to the rectangle when the light bulb is being clicked.
I hope you like it,
Bart