Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Manipulating path elements #85

Closed
tkirchm opened this issue Dec 30, 2020 · 5 comments
Closed

Manipulating path elements #85

tkirchm opened this issue Dec 30, 2020 · 5 comments

Comments

@tkirchm
Copy link

tkirchm commented Dec 30, 2020

Hi @bartbutenaers,

any idea how to edit length of path?
I want to show status of my blinds.
LineLength

There are two ways to achieve this I can think of:

  1. New command to set specific part of path.
  2. New command get_attribute to get actual path -> change value by string manipulation (in my example change length of vertical line without knowing where it starts)-> set_attribute.

I would prefer second one as it has more opportunities to change attributes.

@bartbutenaers
Copy link
Owner

bartbutenaers commented Dec 30, 2020

Hi @tkirchm,

Not sure whether I understand it correctly. I would assume you do it like this:

  • You store somewhere (e.g. in context memory) the current level XX of your blinds.
  • The path of your blinds is M256.409,423.964vXX where XX ranges from 48 (blinds down) to 0 (blinds up).
  • Every time the level of your blinds changes, you store the new level on the server (e.g. in context memory).
  • As soon as the level on the server changes, you update the ENTIRE path with a set_attribute command.

Is there something that I have overlooked?

@bartbutenaers
Copy link
Owner

bartbutenaers commented Dec 30, 2020

I mean something like this:

image

[{"id":"4e273549.9a90ac","type":"inject","z":"7f1827bd.8acfe8","name":"Sensor A = ON","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"SENSOR_A","payload":"ON","payloadType":"str","x":360,"y":2020,"wires":[["2612c30a.10e16c"]]},{"id":"900291ac.fcd07","type":"inject","z":"7f1827bd.8acfe8","name":"Sensor A = OFF","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"SENSOR_A","payload":"OFF","payloadType":"str","x":360,"y":2060,"wires":[["2612c30a.10e16c"]]},{"id":"25bae59e.b13fea","type":"comment","z":"7f1827bd.8acfe8","name":"Sensor values arriving from anywhere (MQTT, GPIO, ....)","info":"","x":370,"y":2100,"wires":[]},{"id":"2612c30a.10e16c","type":"change","z":"7f1827bd.8acfe8","name":"Store on flow memory","rules":[{"t":"set","p":"SENSOR_A","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":600,"y":2020,"wires":[["623f05b6.ac76ac"]]},{"id":"7ea64feb.98a6f","type":"inject","z":"7f1827bd.8acfe8","name":"Load from flow memory at startup","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"SENSOR_A","payload":"SENSOR_A","payloadType":"flow","x":560,"y":1960,"wires":[["623f05b6.ac76ac"]]},{"id":"623f05b6.ac76ac","type":"change","z":"7f1827bd.8acfe8","name":"Construct command","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\t   \"command\":\"update_attribute\",\t   \"selector\":\"#sensor_a\",\t   \"attributeName\":\"fill\",\t   \"attributeValue\": payload = \"ON\" ? \"blue\" : \"red\"\t}","tot":"jsonata"},{"t":"delete","p":"topic","pt":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":860,"y":2020,"wires":[["8570c9cc.c80118"]]},{"id":"8570c9cc.c80118","type":"ui_svg_graphics","z":"7f1827bd.8acfe8","group":"d4b5416a.9c25f","order":1,"width":"14","height":"10","svgString":"<svg preserveAspectRatio=\"none\" x=\"0\" y=\"0\" viewBox=\"0 0 900 710\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:svg=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n  <circle id=\"sensor_a\" cx=\"50\" cy=\"50\" r=\"20\" stroke-width=\"0\" fill=\"#FF0000\" />\n</svg> ","clickableShapes":[{"targetId":"#camera_living","action":"click","payload":"camera_living","payloadType":"str","topic":"camera_living"}],"javascriptHandlers":[],"smilAnimations":[],"bindings":[{"selector":"#banner","bindSource":"payload.title","bindType":"text","attribute":""},{"selector":"#camera_living","bindSource":"payload.position.x","bindType":"attr","attribute":"x"},{"selector":"#camera_living","bindSource":"payload.camera.colour","bindType":"attr","attribute":"fill"}],"showCoordinates":false,"autoFormatAfterEdit":false,"showBrowserErrors":true,"showBrowserEvents":false,"enableJsDebugging":false,"sendMsgWhenLoaded":false,"outputField":"","editorUrl":"http://drawsvg.org/drawsvg.html","directory":"","panning":"disabled","zooming":"disabled","panOnlyWhenZoomed":false,"doubleClickZoomEnabled":false,"mouseWheelZoomEnabled":false,"dblClickZoomPercentage":"150","name":"","x":1100,"y":2020,"wires":[[]]},{"id":"d4b5416a.9c25f","type":"ui_group","z":"","name":"Floorplan test","tab":"b9052fac.2b0e9","order":1,"disp":true,"width":"14","collapse":false},{"id":"b9052fac.2b0e9","type":"ui_tab","z":"","name":"SVG","icon":"dashboard","disabled":false,"hidden":false}]

When you update your Node-RED settings to store the context memory, the context memory will automatically be restored after a restart (so your sensor values will be remembered)...

@tkirchm
Copy link
Author

tkirchm commented Dec 31, 2020

It has nothing to do with memory and global. On the long run this information will come from storage or sensors but right now its just how to manipulate an existing path.
[{"id":"e3cb5f80.1488a","type":"function","z":"b7209503.a11f58","name":"SetAttribute","func":"if (msg.topic == \"get_attribute\") {\n//msg should also contain old msg.payload to determine what was aked for\n\nvar str = msg.payload // output of get_attribute\n\nvar regex = /[a-z][^a-z]*/ig;\nvar sa = str.match(regex);\nsa[1] = \"v50\" //get from external IO from global or direct via msg\nvar s = sa.join('')\n\nmsg.payload = {\n \"command\": \"set_attribute\", //information from get_attribute\n \"selector\": \"#Rs_EsstischStatus\", //information from get_attribute\n \"attributeName\": \"d\",\n \"attributeValue\": s\n}\nreturn msg;\n}","outputs":1,"noerr":0,"x":770,"y":960,"wires":[["6daff55a.61039c"]]},{"id":"6daff55a.61039c","type":"ui_svg_graphics","z":"b7209503.a11f58","group":"d6a8741e.15ed58","order":4,"width":"30","height":"15","svgString":"<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0\" y=\"0\" height=\"700\" viewBox=\"0 -0.09671179950237274 1500 700.1934204101562\" width=\"1500\" preserveAspectRatio=\"xMidYMid meet\"><rect id=\"svgEditorBackground\" x=\"0\" y=\"-0.09671179205179214\" width=\"1500\" height=\"700.1934204101562\" style=\"fill: none; stroke: none;\"/>\n <path d=\"M256.409,423.964v48\" style=\"fill:none;stroke:darkturquoise;stroke-width:30;\" id=\"Rs_EsstischStatus\"/>\n<rect x=\"237.671\" y=\"420.019\" style=\"stroke: black; stroke-width: 1px;fill:none;\" id=\"e1_rectangle\" width=\"37.475\" height=\"56.213\"/></svg>","clickableShapes":[{"targetId":"[id^=\"Li_\"]","action":"click","payload":"EG","payloadType":"str","topic":"[id^=\"Li_\"]"},{"targetId":"[id^=\"Rs_\"]","action":"click","payload":"[id^=\"Rs_\"]","payloadType":"str","topic":"[id^=\"Rs_\"]"},{"targetId":"[id^=\"Ro_\"]","action":"click","payload":"[id^=\"Ro_\"]","payloadType":"str","topic":"[id^=\"Ro_\"]"}],"javascriptHandlers":[],"smilAnimations":[],"bindings":[],"showCoordinates":false,"autoFormatAfterEdit":false,"showBrowserErrors":false,"showBrowserEvents":false,"enableJsDebugging":false,"sendMsgWhenLoaded":false,"outputField":"payload","editorUrl":"http://drawsvg.org/drawsvg.html","directory":"","panning":"disabled","zooming":"disabled","panOnlyWhenZoomed":false,"doubleClickZoomEnabled":false,"mouseWheelZoomEnabled":false,"dblClickZoomPercentage":"150","name":"Test","x":550,"y":900,"wires":[["e3cb5f80.1488a"]]},{"id":"f137e58e.9e54a8","type":"comment","z":"b7209503.a11f58","name":"length of path","info":"","x":420,"y":820,"wires":[]},{"id":"ddc7e600.8be538","type":"function","z":"b7209503.a11f58","name":"get_atribute","func":"msg.payload = {\n \"command\": \"get_attribute\",\n \"selector\": \"#Rs_EsstischStatus\",\n \"attributeName\": \"d\",\n}\nreturn msg;","outputs":1,"noerr":0,"x":390,"y":900,"wires":[["6daff55a.61039c"]]},{"id":"d6a8741e.15ed58","type":"ui_group","z":"","name":"WZ","tab":"6cb18d06.187a14","order":1,"disp":true,"width":"100","collapse":true},{"id":"6cb18d06.187a14","type":"ui_tab","z":"","name":"Plan","icon":"dashboard","disabled":false,"hidden":false}]
For presistant memory I prefer Postgres as it is running on my raspi anyway.

@bartbutenaers
Copy link
Owner

@tkirchm,

I have added a new section to the readme.

You can now replace parts of an attribute value via an msg.

Here is your flow:

image

[{"id":"6daff55a.61039c","type":"ui_svg_graphics","z":"7f1827bd.8acfe8","group":"d6a8741e.15ed58","order":4,"width":"30","height":"15","svgString":"<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0\" y=\"0\" height=\"700\" viewBox=\"0 -0.09671179950237274 1500 700.1934204101562\" width=\"1500\" preserveAspectRatio=\"xMidYMid meet\"><rect id=\"svgEditorBackground\" x=\"0\" y=\"-0.09671179205179214\" width=\"1500\" height=\"700.1934204101562\" style=\"fill: none; stroke: none;\"/>\n <path d=\"M256.409,423.964v48\" style=\"fill:none;stroke:darkturquoise;stroke-width:30;\" id=\"Rs_EsstischStatus\"/>\n<rect x=\"237.671\" y=\"420.019\" style=\"stroke: black; stroke-width: 1px;fill:none;\" id=\"e1_rectangle\" width=\"37.475\" height=\"56.213\"/></svg>","clickableShapes":[{"targetId":"[id^=\"Li_\"]","action":"click","payload":"EG","payloadType":"str","topic":"[id^=\"Li_\"]"},{"targetId":"[id^=\"Rs_\"]","action":"click","payload":"[id^=\"Rs_\"]","payloadType":"str","topic":"[id^=\"Rs_\"]"},{"targetId":"[id^=\"Ro_\"]","action":"click","payload":"[id^=\"Ro_\"]","payloadType":"str","topic":"[id^=\"Ro_\"]"}],"javascriptHandlers":[],"smilAnimations":[],"bindings":[],"showCoordinates":false,"autoFormatAfterEdit":false,"showBrowserErrors":false,"showBrowserEvents":false,"enableJsDebugging":false,"sendMsgWhenLoaded":false,"outputField":"payload","editorUrl":"http://drawsvg.org/drawsvg.html","directory":"","panning":"disabled","zooming":"disabled","panOnlyWhenZoomed":false,"doubleClickZoomEnabled":false,"mouseWheelZoomEnabled":false,"dblClickZoomPercentage":"150","name":"Test","x":510,"y":2620,"wires":[[]]},{"id":"982109e1.78d568","type":"inject","z":"7f1827bd.8acfe8","name":"Replace","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"command\":\"replace_attribute\",\"selector\":\"#Rs_EsstischStatus\",\"attributeName\":\"d\",\"regex\":\"[a-z][^a-z]*\",\"replaceValue\":\"v20\"}","payloadType":"json","x":340,"y":2620,"wires":[["6daff55a.61039c"]]},{"id":"337fbd68.322d82","type":"inject","z":"7f1827bd.8acfe8","name":"Replace all","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"command\":\"replace_all_attribute\",\"selector\":\"#Rs_EsstischStatus\",\"attributeName\":\"d\",\"regex\":\"[a-z][^a-z]*\",\"replaceValue\":\"v20\"}","payloadType":"json","x":340,"y":2660,"wires":[["6daff55a.61039c"]]},{"id":"d6a8741e.15ed58","type":"ui_group","z":"","name":"WZ","tab":"6cb18d06.187a14","order":1,"disp":true,"width":"100","collapse":true},{"id":"6cb18d06.187a14","type":"ui_tab","z":"","name":"Plan","icon":"dashboard","disabled":false,"hidden":false}]

You can install the Github version within your .node-red folder:

npm install bartbutenaers/node-red-contrib-ui-svg

@tkirchm
Copy link
Author

tkirchm commented Jan 1, 2021

works great.
Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants