Image selection by comparison version 2

Good morning,

I'm relaunching a post to move forward with the image selection through comparisons because I had put a little aside.

Here is the first topic I started:

https://discourse.nodered.org/t/image-selection-by-comparison/91043

I tried to link in my template node as I was advised :

Here is the flow I set up:

[
    {
        "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": 390,
        "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": 440,
        "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": 390,
        "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": 750,
        "y": 360,
        "wires": [
            [],
            [
                "47d95921ea509417",
                "76db506634486e02"
            ]
        ]
    },
    {
        "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": 750,
        "y": 400,
        "wires": [
            [
                "47d95921ea509417",
                "76db506634486e02"
            ],
            [
                "47d95921ea509417",
                "76db506634486e02"
            ]
        ]
    },
    {
        "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": 130,
        "y": 280,
        "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": 130,
        "y": 500,
        "wires": []
    },
    {
        "id": "47d95921ea509417",
        "type": "debug",
        "z": "a3c2cda0fd0187df",
        "name": "debug 142",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": true,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "payload",
        "statusType": "auto",
        "x": 870,
        "y": 280,
        "wires": []
    },
    {
        "id": "76db506634486e02",
        "type": "ui-template",
        "z": "a3c2cda0fd0187df",
        "group": "d8041a2154939ee4",
        "page": "",
        "ui": "",
        "name": "",
        "order": 2,
        "width": 0,
        "height": 0,
        "head": "",
        "format": "<template>\n\n    <div>\n        <img :scr = \"img\"  style=\"width:100%\">\n    </div>\n\n</template>\n\n<script>\n\nvar img;\nvar ouvert = \"/ouvert.png\";\nvar ferme = \"/ferme.png\";\nvar portillon = \"/portillon.png\";\n\nif (payload.open == 1 && payload.close == 0){\n    var img = ferme;\n}\n\nif (payload.open == 0 && payload.close == 1){\nvar img = ouvert;\n}\n\nif (payload.open == 0 && payload.close == 1){\nvar img = portillon;\n}\n\n </script>   \n",
        "storeOutMessages": true,
        "passthru": true,
        "resendOnRefresh": true,
        "templateScope": "local",
        "className": "",
        "x": 920,
        "y": 380,
        "wires": [
            [
                "27c10d8b1d73987f"
            ]
        ]
    },
    {
        "id": "27c10d8b1d73987f",
        "type": "debug",
        "z": "a3c2cda0fd0187df",
        "name": "debug 155",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": true,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "payload",
        "statusType": "auto",
        "x": 890,
        "y": 460,
        "wires": []
    },
    {
        "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"
        }
    }
]

Can you tell me if the script is good? and know what is blocking the display of the corresponding image ?

Thank you in advance for your help

Here is the last template I just made:

<template>
    <div>
        <img :src="img" style="width: 100%">
    </div>
</template>

<script>
    export default {
  data() {
    return {
      img: '',  
    };
  },

  created() {
  var payload = {
  open: 0, 
  close: 1, 
  };

    if (payload.open === 1 && payload.close === 0) {
      this.img = "/ferme.png"; 
    } else if (payload.open === 0 && payload.close === 1) {
      this.img = "/ouvert.png";  
    } else if (payload.open === 0 && payload.close === 0) {
      this.img = "/portillon.png";  
    }
  }
  
};

</script>

In the part created(), I don't see how to monitor the open and close value ui can both vary.
here is the nodered debud window :

Your template is invalid. Please read the docs: Template ui-template | Node-RED Dashboard 2.0

You don't need to declare payload, the msg object is provided automatically.

I tried this new approach:

<template>
  <div>
    <img :src="img" style="width: 100%">
  </div>
</template>

<script>
  export default {
  data() {
    return {
      img: '',  
    };
  },

  props: {
    msg: Object, 
  },

  watch: {
    msg: function(newMsg) {
      if (payload.open === 1 && payload.close === 0) {
        this.img = "/ferme.png";  
      } else if (payload.open === 0 && payload.close === 1) {
        this.img = "/ouvert.png";  
      } else if (payload.open === 0 && payload.close === 0) {
        this.img = "/portillon.png";  
      }
      this.sendImageToNodeRed(this.img);
    },
  },

  methods: {    
    sendImageToNodeRed(image) {
            this.$emit('send', image); 
    }
  }
};
</script>

unfortunately, it doesn't work, I have doubts about the function

watch: {
    msg: function(newMsg) {
      if (payload.open === 1 && payload.close === 0) {
        this.img = "/ferme.png";  
      } else if (payload.open === 0 && payload.close === 1) {
        this.img = "/ouvert.png";  
      } else if (payload.open === 0 && payload.close === 0) {
        this.img = "/portillon.png";  
      }
      this.sendImageToNodeRed(this.img);

what do you think of the reading and interaction of the two variables present in the function ?
Note that the path of each payload input to the template node is:

  • payload.open
  • payload.close

No it won't. As I said before,

I.e. this is not necessary:


Also, this is not how you send to node-red:

... please read: Template ui-template | Node-RED Dashboard 2.0 - It is simply this.send

Here is a new model :

<template>
  <div>
    <img :src="img" style="width: 100%">
  </div>
</template>

<script>
  export default {
  data() {
    return {
      img: '',  
    };
  },

  watch: {
    img(msg) {
      if (payload.open === 1 && payload.close === 0) {
        this.img = "/ferme.png";  
      } else if (payload.open === 0 && payload.close === 1) {
        this.img = "/ouvert.png";  
      } else if (payload.open === 0 && payload.close === 0) {
        this.img = "/portillon.png";  
      }
      this.send({payload: this.img});
    },
  },
};
</script>

I still don't have any image display.
Thank you for helping me with your links to help me move forward in learning, it avoids abandoning the project and helps me progress but it's not easy.

Your watch should be watching the msg not the img - so that when the msg changes you update the img

Something like

  watch: {
    "msg.payload": function(payload) {
         // Do stuff
     }

I updated the code and commented out several lines

<template>
  <div>
    <img :src="img" style="width: 100%"> // Refreshed the image on my web page
  </div>
</template>

<script>
  export default {
  data() {
    return {
      img:''; // value of the img variable updated readable by scr in the template
    };
  },

  watch: { 
    "msg.payload" fonction(payload) {  // allows you to read the msg.payload
     if (this.payload.open === 1 && this.payload.close === 0) { // compares the two objects contained in my msg.payload
        this.img = "/ferme.png";  // updates the img variable
      } else if (this.payload.open === 0 && this.payload.close === 1) { // Should we put the prefix this.payload.open or payload.open in the comparison ?
        this.img = "/ouvert.png";  
      } else if (this.payload.open === 1 && this.payload.close === 1) {
        this.img = "/portillon.png";  
      }
      this.send(img); // send the data of the img variable to nodered
    },
  },
};
</script>

It still doesn't work.
Can you tell me if the understanding of the commented lines is correct?

That's nothing like what I wrote. Spelling & Syntax is critical in programming!

Check again.

<template>
  <div>
    <img :src="img" style="width: 100%">
  </div>
</template>

<script>
  export default {
  data() {
    return {
      img:'';
    };
  },

  watch: { 

     function updateImage(msg.payload.open, msg.payload.close) {

     if (msg.payload.open === 1 && msg.payload.close === 0) {
        this.img; = "/ferme.png"; 
      } else if (msg.payload.open === 0 && msg.payload.close === 1) {
        this.img; = "/ouvert.png"; 
      } else if (msg.payload.open === 1 && msg.payload.close === 1) {
        this.img; = "/portillon.png";  
      }   
    this.send(this.img);
    },
  },
};
</script>

Is the syntax better?

No. That is nothing like what I suggested.

What does the parameter"msg.payload": that is placed before the function function(payload) ?
I can't find an example that explains this in the javascript documentation.

It is vue watcher syntax.

So the function Watch targets the object "msg.payload" , on the other hand should we integrate arguments pointing to the two objects "payload.open and payload.close" which are contained in the "msg.payload" and what is well recognized in the conditions of the function?

I tried to declare variables, does the code improve?

<template>
  <div>
    <img :src="img" style="width: 100%">
  </div>
</template>

<script>
  export default {
  data() {
    return {
      img:'';
    };
  },

  watch: { 

      "msg.payload": function() {

let this.img;
let this.capteurOuvert = "payload.open";
let this.capteurFerme = "payload.close";

     if (this.capteurOuvert === 1 && this.capteurFerme === 0) {
        this.img = "/ferme.png"; 
      } else if (this.capteurOuvert === 0 && this.capteurFerme === 1) {
        this.img = "/ouvert.png"; 
      } else if (this.capteurOuvert === 1 && this.capteurFerme === 1) {
        this.img = "/portillon.png";  
      }   
    this.send(this.img);
    },
  },
};
</script>

any idea to continue my progress?

You cannot declare anything with dot notation.

I.e. these :point_up: are all invalid and in the wrong place.

capteurFerme and capteurOuvert should be set-up in data object like you did for img but tbh, I have no idea what your actual goal is (so I can only comment on your mistakes). Also, I am away from computers until Wednesday so cannot help further.

You really need to read the documentation pointed to by Steve at the start of this conversation. I would also suggest you read the info pointed to by the 'document' tab at the top of the page to understand how Node-RED works.
Having said that here is one way to get your result.

<template>
    <div>
        <img :src="img" style="width: 100%">
    </div>
</template>

<script>
    export default {
        data() {
            return {
                img:''
            }
        },

    watch: { 
       msg: function() {
            this.img = ''
            let capteurOuvert = this.msg.payload?.open ?? 0                 // Default to 0 if no input
            let capteurFerme = this.msg.payload?.close ?? 0                 // Default to 0 if no input

            if (capteurOuvert === 1 && capteurFerme === 0) {
                this.img = "/ferme.png";
            } else if (capteurOuvert === 0 && capteurFerme === 1) {
                this.img = "/ouvert.png" 
            } else if (capteurOuvert === 1 && capteurFerme === 1) {
                this.img = "/portillon.png"  
            }

            this.send(this.img)
        },
    },

}

</script>

Thank you for sharing the code, everything works fine, I wasn't missing much in the end. I find that concrete examples are more educational than spending all your time not being sure of yourself and therefore not being on lines that you add. To progress a little further, do you have a good link to learn how to debug at each stage of the code and understand or block a variable?

Thank you for all the links (that I read) but it takes a little time to digest this mass of information

No comment...