bartbutenaers / node-red-contrib-ui-svg

A Node-RED widget node to show interactive SVG (vector graphics) in the dashboard
Apache License 2.0
94 stars 27 forks source link

Saving state, command: "get_svg" ignored #92

Closed Achronite closed 3 years ago

Achronite commented 3 years ago

I'm looking for a way to save the state of my floorplan dashboard implemented with this, as I'm using messages to set the colours of fontawesome icons. I have seen that a command can be sent in to output the current SVG, which I thought I could retrieve on initial display. But this request is being completely ignored for my SVG, and I'm not getting an output payload. Here is my msg object:

msg : Object
  object
  _msgid: "b01e597a.a78908"
  payload: object
    command: "get_svg"

The example flow works fine with the same inject node. I'm wondering are there any limits on the size of the SVG output that may be stopping it being output at all?

bartbutenaers commented 3 years ago

Hi @Achronite, I'm recovering from a surgery, so no debugging fot me unfortunately for quite some time. So cannot determine now why it does't work...

Anyway it looks like you want to abuse the get_svg command. Note that the documentation also points out that this only makes sense when it is triggered from the dashboard, not from your flow.

This has been discussed already a couple of times in depth in other issues, and on Discourse. You want to store the server state of the svg in the dashboard, and retrieve it there from you flow. So if N svg's are currently displayed in N dashboards, then you would retrieve the SVG N times (where N can be 0 if no dashboard).

What you should do instead, is store the state of your sensors in the flow, and generate commands (from these stored sensor values) when:

  1. A sensor value changes (for existing dashboard sesions).
  2. A new dashboard session is opened

Perhaps this example flow might be a place to start. And combine that with this ui_control proposal, in case a new dashboard client connects.

I will try to create a tutorial when I can start with Node-RED again... Bart

Achronite commented 3 years ago

Hi @bartbutenaers, thank you for the reply. I did finally manage to have get_svg return, but the text was truncated and had a '...' on the end.

So, I've gone down the route of saving the state in a global dynamic array, this is then walked through on 'change' event to my floorplan tab to update the icons, using this function code:

var devices = global.get('devices') || [];

devices.forEach(refreshDash);

function refreshDash(device, index, array){
    // format dashboard command
    let dashcmd = {
        "command":"update_style",
        "selector":"#"+device.name,
        "attributeName":"fill",
        "attributeValue":device.fill};
    node.send({payload: dashcmd});
}

I like the idea of changing this to use global context to survive a restart, thanks for the hint I'll try that next.

bartbutenaers commented 3 years ago

Hello @Achronite, Thanks for sharing the code. It might help other users in the future. Bart