Topic not working SORRY! Not it is working

AARRGGHH!

Believe me, it wasn’t working.

Only after I posted it did it start to work.

I am frantically looking how to delete the thread/post, but it still eludes me.

Sorry folks, I’m stuck - again.

Problem:
Two signals into a Function node. (as typical with me)
1 controls what happens to the other input.

The second input msg.payload is modified depending on what the msg.payload of the other input stream is/was.

But the topic for the first input doesn’t seem to be set by the inject node.
Press NORMAL, then press KNOCK KNOCK.
After pressing NORMAL, the second function node sets a yellow flag saying NORMAL.
But NORMAL should NOT be on sent to the output.

Likewise when you press the KNOCK KNOCK injection point, that should become BUZZ.

The KNOCK KNOCK injection point was set to the topic of KNOCK. That didn’t work. See top debug node. All I see is KNOCK KNOCK with no topic shown.
I added the first function node to set the topic, but even that doesn’t seem to be working.

Sorry, buy could someone have a quick look?

[{"id":"b77f100d.befd08","type":"inject","z":"97a50a2e.90f4e","name":"knock knock","topic":"\"","payload":"KNOCK","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":1460,"y":600,"wires":[["efcc64c.6263b98"]]},{"id":"efcc64c.6263b98","type":"function","z":"97a50a2e.90f4e","name":"","func":"msg.topic = \"KNOCK\";\nreturn msg;","outputs":1,"noerr":0,"x":1460,"y":670,"wires":[["1099070c.e158e1","82b0ea91.ae6e8"]]},{"id":"82b0ea91.ae6e8","type":"debug","z":"97a50a2e.90f4e","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":1640,"y":620,"wires":[]},{"id":"1099070c.e158e1","type":"function","z":"97a50a2e.90f4e","name":"","func":"//  Depending on \"mode\" depends on what happens when an input is received.\n//  msg.payload gets parsed and acted upon depending on 'mode'.\n\n\n//  OUTPUT:\n//  msg.payload - OPEN to open door.  BUZZ to sound buzzer.  QUIET to do nothing.\nif (msg.topic != \"KNOCK\")\n{\n    //  This package has the mode.\n    var mode = msg.payload;\n    node.status({fill:\"yellow\",shape:\"dot\",text:mode});\n    context.set('mode',mode);\n    context.set('called',0);\n}\nelse\nif (msg.topic == \"KNOCK\")\n{\n    if (mode == \"NORMAL\")\n    {\n        //  Do the normal thing here.\n        msg.payload = \"BUZZ\";\n    }else\n    if (mode == \"BUSY\")\n    {\n        //  Do the busy stuff.   This is if I am expecting a call and am busy.\n\n    }else\n    if (mode == \"OTO\")\n    {\n        //  Open the door once.\n        //\tSo we now have to clearn the OTO mode too.\n        var called = context.get('called');\n        if (called === 0)\n        {\n            //  Increment called and open door.\n            called = called + 1;\n            msg.payload = \"OPEN\";\n        }\n    }else\n    if (mode == \"CODED\")\n    {\n        //\tLooking for code input.\n\n    }else\n    if (mode == \"DND\")\n    {\n        //\tDo not disturb.  Basically do nothing.\n        msg.payload = \"QUIET\";\n    }\n}\n//  Send msg telling the next stage what to do.\nreturn msg;\n","outputs":1,"noerr":0,"x":1640,"y":670,"wires":[["ff40fc81.0d5b68"]]},{"id":"bc685e56.c22568","type":"inject","z":"97a50a2e.90f4e","name":"","topic":"","payload":"NORMAL","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":1470,"y":780,"wires":[["1099070c.e158e1"]]},{"id":"ff40fc81.0d5b68","type":"debug","z":"97a50a2e.90f4e","name":"Door command","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":1660,"y":810,"wires":[]}]

At line 18 in the function you are testing mode but that variable has not been set so will always be undefined at that point. Possibly you need to precede that line with
var mode = context.get("mode") || "whatever_default_value_want_for_mode_if_it _has_not_been_saved_yet"

A minor point, have a look at the javascript switch statement it is a neater way of doing mulitple if statements on the same variable.

The flow you posted does not have the inject topic set to KNOCK -(though you do set it in the function node afterwards) - you could just set it by moving the KNOCK from the payload to the actual topic parameter below rather than ''
image

Colin,

True. But the mode is not unset for that long.

The trouble was … I can’t remember. Honestly.

decjay,
True too.
That " was an artefact from me trying to set the topic in the inject node.

Originally I put the topic there and it seemed to not be working.
I added a function node to set the topic, and it STILL didn’t set the topic.

I messed around and somehow it suddenly started working: typically a short time after me posting the problem.
Yeah, I know that sounds slack, but again I shall state I am not in the game of wasting people’s time.

I want to learn.

This is that node (only) now and it works.

//  Depending on "mode" depends on what happens when an input is received.
//  msg.payload gets parsed and acted upon depending on 'mode'.


//  OUTPUT:
//  msg.payload - OPEN to open door.  BUZZ to sound buzzer.  QUIET to do nothing.
//                BUSY signal that I am busy.
if (msg.topic != "KNOCK")
{
    //  This package has the mode.
    var mode = msg.payload;
    node.status({fill:"yellow",shape:"dot",text:mode});
    context.set('mode',mode);
    context.set('called',0);
}
else
var mode = context.get('mode');
if (msg.topic == "KNOCK")
{
    if (mode == "NORMAL")
    {
        //  Do the normal thing here.
        msg.payload = "BUZZ";
    }else
    if (mode == "BUSY")
    {
        //  Do the busy stuff.   This is if I am expecting a call and am busy.
        msg.payload = "BUSY";

    }else
    if (mode == "OTO")
    {
        //  Open the door once.
        //	So we now have to clearn the OTO mode too.
        var called = context.get('called');
        if (called === 0)
        {
            //  Increment called and open door.
            called = called + 1;
            context.set('called',called);
            context.set('mode',"NORMAL");
            msg.payload = "OPEN";
        }
    }else
    if (mode == "CODED")
    {
        //	Looking for code input.

    }else
    if (mode == "DND")
    {
        //	Do not disturb.  Basically do nothing.
        msg.payload = "QUIET";
    }
    else
    msg.payload = [];
    //  Send msg telling the next stage what to do.
    return msg;
}

The code has changed a bit because I have since modified what is happening in that node and what messages are sent.

Alas I think even this is not workable for me, as I need (analogue) input monitoring to then determine the output.

I think it would be easier if I just set signal lines that go to a remote device (arduino) and use it as a state machine kind of thing.
It monitors the “analogue” input and determined by the signals from NR it determines what is done when the input is active.

Sorry guys.

On a P.S. How do I delete a thread once I start it?
I’ve seen the “delete THIS post” but not the entire thread.

That is not correct. As you had it the variable mode would never be set at that point in the code.
Also as you have it now, if the first message topic is "KNOCK" you will pass on a message payload as an empty array. Is that what you meant? Perhaps you meant
msg=null
in the else statement, so nothing is sent at all.

A suggestion for coding style, you have

  else
  msg.payload = [];
  return msg;

That is very easy to misinterpret when you come back to modify it later. In particular if you wanted to add another line into the else it would be very easy to accidentally just add it before or after the msg.payload = line. I suggest either using

  else msg.payload = [];
  return msg;

or

  else 
  {
    msg.payload = [];
  }
  return msg;

The same applies to your

  } else 
  if (  )
  {
    ...
  }

I would code them as

  } else if (  )
  {
    ...
  }

which is less error prone I believe. It is a matter of personal preference however and others may disagree.

maybe step away from the keyboard for that short time, take a few deep breaths, and relax, before posting ? I know it can be terribly frustrating, but firing off 3 or 4 posts on topics all at once does not seem to indicate you are trying to debug and understand and learn from each as you go - though I know that is your intention.

dceejay,

I whole heartedly agree that it must be frustrating for people who know this to see someone like me and what I post.

I do step back from the keyboard, walk away and try to clear my head.

Colin,
I do try to put { } around all my code with the if (…) statements.
So it would be something like:

if (j == "fred")
{
    command;
    command;
    command;
}

and I do get the else - now.

I am trying to force myself to include it when doing conditional tests.

So it would be:

if (....)
{
   ....
   ....
} else
if (...)

But what throws me sometimes is the “auto complete” thing where when I do the { it automatically puts the } on the next line.

(as with " and ’ and () )

As I am more of the habit to “cross the t’s and dot the i’s”
I sometimes get something like:

variable = "this is a test";"

and that causes all sorts of problems.

But I guess that is an excuse rather than a reason. But it is how I type. I open a quote, I close a quote. Likewise with ', ( and {.

But thanks. What you have said is something I am trying to enforce myself in doing with structures.

Anyway, I’m back programming for another hour tonight and want to try and get the calculator working.

As I said before I think that this is better as

if (....)
{
   ....
   ....
} else if (...)

so you don't run the risk of adding a line under the else and ending up with

if (....)
{
   ....
   ....
} else
do something;
if (...)

which messes everything up.