or you can change the property in switch nodes to whatever topic your mqtt is pushing.
glad you could find the solution. it is usually encouraged in this forum to just guide and not give solution directly, but as a beginner i have found that sometimes a working solution encourages them to go further and not get frustrated and give up.
this is the best forum i have ever been and am also happy i am able to guide few beginners in basic stuff.
Hello, I am encountering a problem, this flow no longer works on dashboard 2 which I am starting to use.
Is there another method to use for the node Template ?
the flow upto the template node will be same, however DB-2 has a different template format as it is not based on angular but Vue.
someone else will definitley help you, as i am still not well verse with DB2.
Not exactly what you were asking, but relevant to the topic:
This is a use case for the node-red-contrib-finite-statemachine node. You can define a whole state machine that is triggered every few seconds, reads inputs, and jumps to the next state if appropriate.
If you go for the Moore approach of the state machine, the outputs (like the image) depend only of the state in which the machine is at any given time. So it could be Open, Closed, Opening, or Closing (these last two cases would use the same picture, but you could overimpose an SVG arrow on top to show if it's opening or closing).
For applications like this, you can simplify your flows a lot if you just use the finite state machine to define all the states and transitions, and then a subflow (or a function node with a switch-case) with all the transition logic based on inputs.
Coding a Finite State Machine (FSM) in pure JavaScript isn't too difficult.
Here are a couple of examples.
Sure, but this is one of those cases in which a specialised node simplifies the implementation (and makes it much faster).
Granted, in the door example might not be that important, but I've used the node for state machines with more than 70 states and it works like a charm.
Thank you for your answers, I just deleted my entire dashboard (version 1) to concentrate on dashboard 2 and there is a little change anyway. I'm looking for a good tutorial for the basics, do you have any good links to give me?
Not sure if you have read these pages
About Node-RED Dashboard 2.0 | Node-RED Dashboard 2.0 (flowfuse.com)
Hello everyone, I recreated my 2.0 dashboard and I studied the state machine which remains a little vague in the configuration for me. I would first like to know how to integrate a .png image into a âTemplateâ node between my two buttons below :
My image files are located in a folder on my RaspberrryPi5:
/home/img/ouvert.png
/home/img/ferme.png
/home/img/portillon.png
I use the following code to just display the image but it doesn't work.
<template>
<div>
<img :src= "/ouvert.png" alt="Image loaded from the filestore" style="width:100%"><br>
</div>
</template>
I tried to follow the following link but I can't do it either.
https://flowfuse.com/blog/2023/07/images-in-node-red-dashboards/
Can you help me please ?
Have you setup httpStatic
in the settings file to serve these files to the browser?
Example:
Yes, the settings.js file is configured with HTTPstatic. The tempate nodes worked on my dashboard 1.
ok, i spotted your deliberate error
you have :src= "/ouvert.png"
it should be src= "/ouvert.png"
When you put :src="SOMETHING"
you are telling dashboard to evaluate a variable named SOMETHING
and then apply that to the src
attribute.
This :
is for attribute binding in VUE
in other words, the dashboard was trying to evaluate the value of this['/ouvert.png']
- which doesn't exist (i.e. undefined
)
Thanks for spotting the error, it works fine now.
I will try to redo the selection of images from a state machine.
What is the replacement syntax for the selector (mustache) which will replace: img src={{img}}
by VUE compatible syntax in order to select the correct image of the three?
I told you before...
Sorry, it was me who expressed myself incorrectly, there are no two dots ( in the code, here is how it is actually written
Below is the complete code which worked under my dashboard 1 but which no longer works under my dashboard 2
[
{
"id": "05c47a899779d1ba",
"type": "mqtt in",
"z": "a3c2cda0fd0187df",
"name": "",
"topic": "Etat/capteur/portail/ouvert",
"qos": "2",
"datatype": "auto-detect",
"broker": "b690438f99f8231b",
"nl": false,
"rap": true,
"rh": 0,
"inputs": 0,
"x": 150,
"y": 360,
"wires": [
[
"939930196a253988",
"73f3b35b4398ef57"
]
]
},
{
"id": "be6e73f796b9f46c",
"type": "mqtt in",
"z": "a3c2cda0fd0187df",
"name": "",
"topic": "Etat/capteur/portail/ferme",
"qos": "2",
"datatype": "auto-detect",
"broker": "b690438f99f8231b",
"nl": false,
"rap": true,
"rh": 0,
"inputs": 0,
"x": 150,
"y": 420,
"wires": [
[
"9cb6f5ff2f452414",
"a1f18da35dd4a5a8"
]
]
},
{
"id": "939930196a253988",
"type": "change",
"z": "a3c2cda0fd0187df",
"name": "Change topic open",
"rules": [
{
"t": "change",
"p": "topic",
"pt": "msg",
"from": "Etat/capteur/portail/ouvert",
"fromt": "str",
"to": "open",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 410,
"y": 300,
"wires": [
[
"ac4c4104c6383254"
]
]
},
{
"id": "ac4c4104c6383254",
"type": "join",
"z": "a3c2cda0fd0187df",
"name": "Jonction des topics",
"mode": "custom",
"build": "object",
"property": "payload",
"propertyType": "msg",
"key": "topic",
"joiner": "\\n",
"joinerType": "str",
"accumulate": true,
"timeout": "",
"count": "2",
"reduceRight": false,
"reduceExp": "",
"reduceInit": "",
"reduceInitType": "",
"reduceFixup": "",
"x": 430,
"y": 380,
"wires": [
[
"91533b8eec6b8189"
]
]
},
{
"id": "9cb6f5ff2f452414",
"type": "change",
"z": "a3c2cda0fd0187df",
"name": "Change topic close",
"rules": [
{
"t": "change",
"p": "topic",
"pt": "msg",
"from": "Etat/capteur/portail/ferme",
"fromt": "str",
"to": "close",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 410,
"y": 480,
"wires": [
[
"ac4c4104c6383254"
]
]
},
{
"id": "91533b8eec6b8189",
"type": "switch",
"z": "a3c2cda0fd0187df",
"name": "Open",
"property": "payload.open",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "0",
"vt": "num"
},
{
"t": "eq",
"v": "1",
"vt": "num"
}
],
"checkall": "true",
"repair": false,
"outputs": 2,
"x": 630,
"y": 380,
"wires": [
[
"212535da6fa112f5"
],
[
"f55fb38745c98c88"
]
]
},
{
"id": "212535da6fa112f5",
"type": "switch",
"z": "a3c2cda0fd0187df",
"name": "Close",
"property": "payload.close",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "0",
"vt": "num"
},
{
"t": "eq",
"v": "1",
"vt": "num"
}
],
"checkall": "true",
"repair": false,
"outputs": 2,
"x": 630,
"y": 300,
"wires": [
[],
[
"32eb3b37e2ef367c"
]
]
},
{
"id": "f55fb38745c98c88",
"type": "switch",
"z": "a3c2cda0fd0187df",
"name": "Close",
"property": "payload.close",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "0",
"vt": "num"
},
{
"t": "eq",
"v": "1",
"vt": "num"
}
],
"checkall": "true",
"repair": false,
"outputs": 2,
"x": 630,
"y": 460,
"wires": [
[
"70b64063517a6ed9"
],
[
"c8a571bb6fb20f87"
]
]
},
{
"id": "32eb3b37e2ef367c",
"type": "change",
"z": "a3c2cda0fd0187df",
"name": "Open:0 Close-1 \\n OPEN",
"rules": [
{
"t": "set",
"p": "img",
"pt": "msg",
"to": "/ouvert.png",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 820,
"y": 300,
"wires": [
[
"65882687c2bbf1e8"
]
]
},
{
"id": "70b64063517a6ed9",
"type": "change",
"z": "a3c2cda0fd0187df",
"name": "Open:1 Close:0 \\n CLOSED",
"rules": [
{
"t": "set",
"p": "img",
"pt": "msg",
"to": "/ferme.png",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 820,
"y": 420,
"wires": [
[
"65882687c2bbf1e8"
]
]
},
{
"id": "c8a571bb6fb20f87",
"type": "change",
"z": "a3c2cda0fd0187df",
"name": "Open:1 Close:1 \\n PARTIALLY OPEN",
"rules": [
{
"t": "set",
"p": "img",
"pt": "msg",
"to": "/portillon.png",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 830,
"y": 520,
"wires": [
[
"65882687c2bbf1e8"
]
]
},
{
"id": "73f3b35b4398ef57",
"type": "debug",
"z": "a3c2cda0fd0187df",
"name": "Ouvert",
"active": true,
"tosidebar": false,
"console": false,
"tostatus": true,
"complete": "payload",
"targetType": "msg",
"statusVal": "payload",
"statusType": "auto",
"x": 190,
"y": 300,
"wires": []
},
{
"id": "a1f18da35dd4a5a8",
"type": "debug",
"z": "a3c2cda0fd0187df",
"name": "Fermé",
"active": true,
"tosidebar": false,
"console": false,
"tostatus": true,
"complete": "payload",
"targetType": "msg",
"statusVal": "payload",
"statusType": "auto",
"x": 190,
"y": 480,
"wires": []
},
{
"id": "02c7dfa32b4a25ec",
"type": "ui-template",
"z": "a3c2cda0fd0187df",
"group": "d8041a2154939ee4",
"page": "",
"ui": "",
"name": "Display the image on the Dashboard",
"order": 2,
"width": 0,
"height": 0,
"head": "",
"format": "",
"storeOutMessages": true,
"passthru": true,
"resendOnRefresh": true,
"templateScope": "local",
"className": "",
"x": 1250,
"y": 420,
"wires": [
[]
]
},
{
"id": "65882687c2bbf1e8",
"type": "template",
"z": "a3c2cda0fd0187df",
"name": "",
"field": "payload",
"fieldType": "msg",
"format": "handlebars",
"syntax": "mustache",
"template": "<template>\n <div>\n <img src= {{img}} alt=\"Image loaded from the filestore\" style=\"width:100%\"><br>\n </div>\n</template>",
"output": "str",
"x": 1000,
"y": 420,
"wires": [
[
"02c7dfa32b4a25ec"
]
]
},
{
"id": "b690438f99f8231b",
"type": "mqtt-broker",
"name": "",
"broker": "192.168.1.13",
"port": "1883",
"clientid": "",
"autoConnect": true,
"usetls": false,
"protocolVersion": "4",
"keepalive": "60",
"cleansession": true,
"autoUnsubscribe": true,
"birthTopic": "",
"birthQos": "0",
"birthRetain": "false",
"birthPayload": "",
"birthMsg": {},
"closeTopic": "",
"closeQos": "0",
"closeRetain": "false",
"closePayload": "",
"closeMsg": {},
"willTopic": "",
"willQos": "0",
"willRetain": "false",
"willPayload": "",
"willMsg": {},
"userProps": "",
"sessionExpiry": ""
},
{
"id": "d8041a2154939ee4",
"type": "ui-group",
"name": "Portail d'entrée",
"page": "242784246503bab6",
"width": "6",
"height": "1",
"order": 1,
"showTitle": true,
"className": "",
"visible": "true",
"disabled": "false"
},
{
"id": "242784246503bab6",
"type": "ui-page",
"name": "Portails",
"ui": "acf62d88f4bd3d87",
"path": "portails",
"icon": "home",
"layout": "grid",
"theme": "18acbce16a65bbb8",
"breakpoints": [
{
"name": "Default",
"px": "0",
"cols": "3"
},
{
"name": "Tablet",
"px": "576",
"cols": "6"
},
{
"name": "Small Desktop",
"px": "768",
"cols": "9"
},
{
"name": "Desktop",
"px": "1024",
"cols": "12"
}
],
"order": 1,
"className": "",
"visible": "true",
"disabled": "false"
},
{
"id": "acf62d88f4bd3d87",
"type": "ui-base",
"name": "Maison",
"path": "/dashboard",
"includeClientData": true,
"acceptsClientConfig": [
"ui-notification",
"ui-control"
],
"showPathInSidebar": false,
"showPageTitle": true,
"navigationStyle": "default",
"titleBarStyle": "default"
},
{
"id": "18acbce16a65bbb8",
"type": "ui-theme",
"name": "Default Theme",
"colors": {
"surface": "#9ba50e",
"primary": "#0094ce",
"bgPage": "#eeeeee",
"groupBg": "#474747",
"groupOutline": "#000000"
},
"sizes": {
"density": "default",
"pagePadding": "12px",
"groupGap": "12px",
"groupBorderRadius": "4px",
"widgetGap": "12px"
}
}
]
There should be. And by two dots I assume you are referring to the :
colon.
Please read again what i have written twice now.
and that is wrong for dashboard 2
dashboard to uses VUE. Vue uses attribute binding. I have also provide a link to a help source.
Here it is again...
So you should use that e.g. :img="your_variable"
Also, if you are expecting to use img
from the msg
object, the HTML attribute should be bound to msg.img
e.g :img="msg.img"