# State Machine - How to Compare Numbers?

**URL:** <https://discourse.nodered.org/t/state-machine-how-to-compare-numbers/71340>\
**Category:** General\
**Tags:** node-red-dashboard, function-node\
**Created:** [27 November 2022 20:53 UTC](https://discourse.nodered.org/t/state-machine-how-to-compare-numbers/71340 "2022-11-27T20:53:58Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![wilwizard1979](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/wilwizard1979/32/71452_2.png) [@wilwizard1979](https://discourse.nodered.org/u/wilwizard1979)\
**Post date:** [27 November 2022 20:53 UTC](https://discourse.nodered.org/t/state-machine-how-to-compare-numbers/71340/1 "2022-11-27T20:53:58Z")

</div>

Hello, I´m trying to learn and do some tests with the State Machine Node, but I´m having problems to use number comparisons. The = works fine, but the \> #number seems to require a certain syntax that I´m not sure.

Below the very simple flow I´m testing:

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/9/b/9b76e1ebe5f472edb4e64cb04794cf8a0f152392.png)

And the configuration inside:

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/5/3/53e71222ea80631fa49fd59a6db985aa744d5d29.png)

The \>400 doesn´t work and it seems the Node waits for a string "\>400" but not an actual number that is over 400.

The trigger State Node is configured to Number.  
What am I doing wrong?

---

<div class="post-metadata">

**Author:** ![zenofmud](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/zenofmud/32/316_2.png) [@zenofmud](https://discourse.nodered.org/u/zenofmud)\
**Post date:** [27 November 2022 21:14 UTC](https://discourse.nodered.org/t/state-machine-how-to-compare-numbers/71340/2 "2022-11-27T21:14:56Z")

</div>

It looks like you are using node-red-contrib-state-machine. That node hasn’t been updated in over 5 years. You could raise an issue with the author:

> **[GitHub - DeanCording/node-red-contrib-state-machine: A Node Red node that...](https://github.com/DeanCording/node-red-contrib-state-machine)**
>
> A Node Red node that wraps around Javascript State Machine - GitHub - DeanCording/node-red-contrib-state-machine: A Node Red node that wraps around Javascript State Machine

You may want to read the issue ‘State machine makes use of a deprecated function’ or ask on the HomeAssistant forum for what people are using as a replacement.

---

<div class="post-metadata">

**Author:** ![wilwizard1979](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/wilwizard1979/32/71452_2.png) [@wilwizard1979](https://discourse.nodered.org/u/wilwizard1979)\
**Post date:** [27 November 2022 21:39 UTC](https://discourse.nodered.org/t/state-machine-how-to-compare-numbers/71340/3 "2022-11-27T21:39:28Z")

</div>

Hi Zenofmud,

I´m actually using this one:

[https://github.com/hufftheweevil/node-red-contrib-persistent-fsm](https://github.com/hufftheweevil/node-red-contrib-persistent-fsm)

It seems to be quite new. But you gave me a good idea to ask directly there.  
Thanks a lot.

---

<div class="post-metadata">

**Author:** ![zenofmud](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/zenofmud/32/316_2.png) [@zenofmud](https://discourse.nodered.org/u/zenofmud)\
**Post date:** [27 November 2022 21:46 UTC](https://discourse.nodered.org/t/state-machine-how-to-compare-numbers/71340/4 "2022-11-27T21:46:57Z")

</div>

It helps to identify, using the full name, when referring to a node. It also saves the time of anyone trying to help you.

---

<div class="post-metadata">

**Author:** ![wilwizard1979](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/wilwizard1979/32/71452_2.png) [@wilwizard1979](https://discourse.nodered.org/u/wilwizard1979)\
**Post date:** [27 November 2022 22:33 UTC](https://discourse.nodered.org/t/state-machine-how-to-compare-numbers/71340/5 "2022-11-27T22:33:07Z")

</div>

Noted for the next time, which will be my second post.

---

<div class="post-metadata">

**Author:** ![dynamicdave](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dynamicdave/32/96_2.png) [@dynamicdave](https://discourse.nodered.org/u/dynamicdave)\
**Post date:** [28 November 2022 05:44 UTC](https://discourse.nodered.org/t/state-machine-how-to-compare-numbers/71340/6 "2022-11-28T05:44:33Z")

</div>

You can also build a FSM using some Javascript in a function node.  
Here's copy of a very simple FSM that mimics the seqence of a UK traffic light.

Note:  
You will need to change the conditions for the state-transitions to suit your application.

 ![UK_Traffic_Light](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/e/a/ea5b8154c34edf6efefb9a5941ad554728ffbab4.png)

```auto
[{"id":"730e90628b9f186a","type":"tab","label":"Simple FSM","disabled":false,"info":"","env":[]},{"id":"760b4fc6.26e1","type":"function","z":"730e90628b9f186a","name":"Decode RED light","func":"var fsm_state = flow.get(\"state_counter\");\n\nif (fsm_state === \"S0\" || fsm_state == \"S1\")\n {msg.payload = 1;\n node.status({fill:\"red\",shape:\"dot\",text:\"Red ON\"});\n }\n \nelse\n {msg.payload = 0;\n node.status({});\n }\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":730,"y":240,"wires":[[]]},{"id":"c24343bf.b80df8","type":"function","z":"730e90628b9f186a","name":"Decode YELLOW light","func":"var fsm_state = flow.get(\"state_counter\");\n\nif (fsm_state == \"S1\" || fsm_state == \"S3\")\n {msg.payload = 1;\n node.status({fill:\"yellow\",shape:\"dot\",text:\"Yellow ON\"});\n }\nelse\n {msg.payload = 0;\n node.status({});}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":740,"y":300,"wires":[[]]},{"id":"6b986e0f.b813b8","type":"function","z":"730e90628b9f186a","name":"Decode GREEN light","func":"var fsm_state = flow.get(\"state_counter\");\n\nif (fsm_state == \"S2\")\n {msg.payload = 1;\n node.status({fill:\"green\",shape:\"dot\",text:\"Green ON\"});\n }\nelse\n {msg.payload = 0;\n node.status({});\n }\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":740,"y":360,"wires":[[]]},{"id":"801d6dfd.1244","type":"inject","z":"730e90628b9f186a","name":"Trigger every 3 seconds","props":[{"p":"payload"}],"repeat":"3","crontab":"","once":true,"onceDelay":"","topic":"","payload":"1","payloadType":"num","x":190,"y":300,"wires":[["d748e7bb.cdeb78"]]},{"id":"d748e7bb.cdeb78","type":"function","z":"730e90628b9f186a","name":"Index the State Counter","func":"// Here is the classical way of coding a state machine.\n// It uses a 'case construct' to check the current state and then set the next state.\n\nvar fsm_state = flow.get(\"state_counter\") || \"S0\";\n\nswitch (fsm_state)\n {\n case \"S0\":\n fsm_state = \"S1\";\n break;\n \n case \"S1\":\n fsm_state = \"S2\";\n break;\n \n case \"S2\":\n fsm_state = \"S3\";\n break;\n \n case \"S3\":\n fsm_state = \"S0\";\n break;\n }\n \nflow.set(\"state_counter\", fsm_state);\nmsg.payload = fsm_state;\nnode.status({text:\"State counter = \" + fsm_state});\n\nreturn msg;","outputs":"1","noerr":0,"initialize":"","finalize":"","libs":[],"x":450,"y":300,"wires":[["760b4fc6.26e1","c24343bf.b80df8","6b986e0f.b813b8"]]},{"id":"4f023541f75009b8","type":"comment","z":"730e90628b9f186a","name":"Simple FSM to mimic the UK traffic light sequence","info":"","x":370,"y":240,"wires":[]}]

```

---

<div class="post-metadata">

**Author:** ![dynamicdave](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dynamicdave/32/96_2.png) [@dynamicdave](https://discourse.nodered.org/u/dynamicdave)\
**Post date:** [28 November 2022 06:56 UTC](https://discourse.nodered.org/t/state-machine-how-to-compare-numbers/71340/7 "2022-11-28T06:56:00Z")

</div>

Just had a few spare minutes, so I quickly built this simple flow. Can you check if it works for you?

![FSM_monday_2](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/7/2/723a6bb19cb9ed32a8c2a3d3faeba56c4149741c.png)

```auto
[{"id":"730e90628b9f186a","type":"tab","label":"Simple FSM","disabled":false,"info":"","env":[]},{"id":"801d6dfd.1244","type":"inject","z":"730e90628b9f186a","name":"0","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":"","topic":"","payload":"0","payloadType":"num","x":150,"y":300,"wires":[["d748e7bb.cdeb78"]]},{"id":"d748e7bb.cdeb78","type":"function","z":"730e90628b9f186a","name":"FSM","func":"// Here is the classical way of coding a state machine.\n// It uses a 'case construct' to check the current state and then set the next state.\n\nif (msg.topic == \"reset\") {\n flow.set(\"state_register\", \"S1\");\n}\n\n\nvar fsm_state = flow.get(\"state_register\") || \"S1\";\n\nswitch (fsm_state)\n {\n case \"S1\":\n if (msg.payload == 100) {\n fsm_state = \"S2\"; \n }\n break;\n \n case \"S2\":\n if (msg.payload == 200) {\n fsm_state = \"S3\";\n }\n break;\n \n case \"S3\":\n if (msg.payload == 300) {\n fsm_state = \"S4\";\n }\n break;\n \n case \"S4\":\n if (msg.payload > 400) {\n fsm_state = \"S1\";\n }\n break;\n }\n \nflow.set(\"state_register\", fsm_state);\nmsg.payload = fsm_state;\nnode.status({text:\"State register = \" + fsm_state});\n\nreturn msg;","outputs":"1","noerr":0,"initialize":"","finalize":"","libs":[],"x":330,"y":300,"wires":[["eab829b3b68ccf9f"]]},{"id":"eab829b3b68ccf9f","type":"debug","z":"730e90628b9f186a","name":"debug 30","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":480,"y":300,"wires":[]},{"id":"32e0a48416d4db02","type":"inject","z":"730e90628b9f186a","name":"Reset to S1","props":[{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"reset","x":170,"y":220,"wires":[["d748e7bb.cdeb78"]]},{"id":"82cc0d69adc947ee","type":"inject","z":"730e90628b9f186a","name":"100","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":"","topic":"","payload":"100","payloadType":"num","x":150,"y":360,"wires":[["d748e7bb.cdeb78"]]},{"id":"e260485be0374b83","type":"inject","z":"730e90628b9f186a","name":"200","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":"","topic":"","payload":"200","payloadType":"num","x":150,"y":420,"wires":[["d748e7bb.cdeb78"]]},{"id":"061eba96ddac281b","type":"inject","z":"730e90628b9f186a","name":"300","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":"","topic":"","payload":"300","payloadType":"num","x":150,"y":480,"wires":[["d748e7bb.cdeb78"]]},{"id":"3876685887570362","type":"inject","z":"730e90628b9f186a","name":"401","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":"","topic":"","payload":"401","payloadType":"num","x":150,"y":540,"wires":[["d748e7bb.cdeb78"]]}]

```

---

<div class="post-metadata">

**Author:** ![wilwizard1979](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/wilwizard1979/32/71452_2.png) [@wilwizard1979](https://discourse.nodered.org/u/wilwizard1979)\
**Post date:** [28 November 2022 12:35 UTC](https://discourse.nodered.org/t/state-machine-how-to-compare-numbers/71340/8 "2022-11-28T12:35:15Z")

</div>

Your code looks simple and effective.  
I added to a new function Node but I could not get it to the initial state. Looking to the code I was supposed to set "reset" to the msg.topic. I did that but no result is seen in my log. I tried also with the numbers directly from my slider, but it seems it needs to get to the initial status first (means "reset" in the msg.topic).

Here it is the way I configured:  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/b/1/b1681e48a9a8829bd2de3c5e1730be79e64a4386.png)

But no result goes out to my debug node 9.

Another question, is there a way to format your code with all Java formatting and identation? It makes much easier to debug and re-work.

Thanks in advance.

---

<div class="post-metadata">

**Author:** ![dynamicdave](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dynamicdave/32/96_2.png) [@dynamicdave](https://discourse.nodered.org/u/dynamicdave)\
**Post date:** [28 November 2022 14:04 UTC](https://discourse.nodered.org/t/state-machine-how-to-compare-numbers/71340/9 "2022-11-28T14:04:34Z")

</div>

Did you try **just** my simple flow to see if it works on your set-up?

It doesn't look as if the FSM is getting reset to the initial state "S1" in YOUR setup.  
You need to fix that issue.

Here's the **Java-Script** code (not Java) formatted as requested.

```auto
// Here is the classical way of coding a state machine.
// It uses a 'case construct' to check the current state and then set the next state.

if (msg.topic == "reset") {
    flow.set("state_register", "S1");
}

var fsm_state = flow.get("state_register") || "S1";

switch (fsm_state) {
    case "S1":
        if (msg.payload == 100) {
            fsm_state = "S2";
        }
        break;

    case "S2":
        if (msg.payload == 200) {
            fsm_state = "S3";
        }
        break;

    case "S3":
        if (msg.payload == 300) {
            fsm_state = "S4";
        }
        break;

    case "S4":
        if (msg.payload > 400) {
            fsm_state = "S1";
        }
        break;
}

flow.set("state_register", fsm_state);
msg.payload = fsm_state;
node.status({ text: "State register = " + fsm_state });

return msg;

```

---

<div class="post-metadata">

**Author:** ![wilwizard1979](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/wilwizard1979/32/71452_2.png) [@wilwizard1979](https://discourse.nodered.org/u/wilwizard1979)\
**Post date:** [28 November 2022 14:51 UTC](https://discourse.nodered.org/t/state-machine-how-to-compare-numbers/71340/10 "2022-11-28T14:51:59Z")

</div>

Dear Dynamicdave,

it works perfectly! Thanks a lot.  
Allow me to make a stupid question. Why most like you send the code in the previous format? It is much more difficult to read and adjust, at least for me. Is it some kind of compilation to support the developer? Or are you using some kind of formatting conversion?

Thanks a lot for your support.

---

<div class="post-metadata">

**Author:** ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)\
**Post date:** [28 November 2022 15:58 UTC](https://discourse.nodered.org/t/state-machine-how-to-compare-numbers/71340/11 "2022-11-28T15:58:58Z")

</div>

The former is actually a complete export of the code as shown in his picture - ie a small test flow... you can use the button one in from top right of that code window  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/f/b/fb83e6f19268c1aaf7baf760facb7dbfc985b179.png)  
to copy the code to your clipboard - then in Node-RED editor you can use Ctrl-I (or Menu - Import) and paste in that code to have it load into your editor... hopefully as a working example 🙂

---

<div class="post-metadata">

**Author:** ![dynamicdave](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dynamicdave/32/96_2.png) [@dynamicdave](https://discourse.nodered.org/u/dynamicdave)\
**Post date:** [28 November 2022 16:31 UTC](https://discourse.nodered.org/t/state-machine-how-to-compare-numbers/71340/12 "2022-11-28T16:31:48Z")

</div>

> [@wilwizard1979](#):
>
> Why most like you send the code in the previous format?

As @dceejay explained, this is the most common way (format) to share Node-RED flows.  
Just follow @dceejay instructions and try it out - it is quite easy once you are familiar with it.

PS: Glad to hear the flow works for you.

---

<div class="post-metadata">

**Author:** ![piwi447](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/piwi447/32/67335_2.png) [@piwi447](https://discourse.nodered.org/u/piwi447)\
**Post date:** [29 November 2022 07:54 UTC](https://discourse.nodered.org/t/state-machine-how-to-compare-numbers/71340/13 "2022-11-29T07:54:08Z")

</div>

Thanks for sharing the code in an easy way,  
It’s also easier for people like me that are learning trough the forum without having the time to test all nodes configuration in node ref.  
Just one question, I saw often in function example a flow.get at the beginning and flow.set at the end but I learned recently that the link for context variable is a reference, so I would say that the flow.set at the end is not useful . Could you confirm it is working the same way when removing it?

Pierre RUWET

---

<div class="post-metadata">

**Author:** ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)\
**Post date:** [29 November 2022 08:06 UTC](https://discourse.nodered.org/t/state-machine-how-to-compare-numbers/71340/14 "2022-11-29T08:06:34Z")

</div>

> [@piwi447](#):
>
> the flow.set at the end is not useful

The answer is sometimes… if you are only using memory based context then yes it will probably work by reference. However if you use any other form of context storage eg file or database then you must explicitly write back to it, so in general it is safer to always get into the good habit and call the write. It is also easier to read later when you need to debug in 6 months time.

---

<div class="post-metadata">

**Author:** ![piwi447](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/piwi447/32/67335_2.png) [@piwi447](https://discourse.nodered.org/u/piwi447)\
**Post date:** [29 November 2022 08:10 UTC](https://discourse.nodered.org/t/state-machine-how-to-compare-numbers/71340/15 "2022-11-29T08:10:57Z")

</div>

Regarding the general subject of state machine, I have been using the node red contrib dsm with success. I found it interesting because there are a lot of examples in the documentation.  
I don’t understand why a node should automatically be considered bad because it had no upgrade for 4 years..  
it just mean for me that the code was very good at the beginning and that no bug where discovered that need an update.  
This is also because it is using basic Java code without external connection, so less need to update.

Pierre RUWET

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [29 November 2022 09:41 UTC](https://discourse.nodered.org/t/state-machine-how-to-compare-numbers/71340/16 "2022-11-29T09:41:01Z")

</div>

> [@piwi447](#):
>
> I would say that the flow.set at the end is not useful

In addition to @dceejay's comment, if the object in context is a simple value rather than an object then I believe you always need flow.set().

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [29 November 2022 10:40 UTC](https://discourse.nodered.org/t/state-machine-how-to-compare-numbers/71340/17 "2022-11-29T10:40:24Z")

</div>

> [@piwi447](#):
>
> I don’t understand why a node should automatically be considered bad because it had no upgrade for 4 years..

A better guide is to look at the issues on its github page and whether they have been answered or not. A node that is not supported may stop working at some point if it becomes incompatible with the latest nodejs.

---

<div class="post-metadata">

**Author:** ![piwi447](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/piwi447/32/67335_2.png) [@piwi447](https://discourse.nodered.org/u/piwi447)\
**Post date:** [1 December 2022 22:29 UTC](https://discourse.nodered.org/t/state-machine-how-to-compare-numbers/71340/18 "2022-12-01T22:29:14Z")

</div>

Thanks for the advice, I will check if I can easily replace my dsm node by dsm or by a function node.  
Contrib node are interesting for people that are not a JS specialist. This is my case. I never used JS before starting with nodered two years ago.

---

<div class="post-metadata">

**Author:** ![wilwizard1979](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/wilwizard1979/32/71452_2.png) [@wilwizard1979](https://discourse.nodered.org/u/wilwizard1979)\
**Post date:** [1 December 2022 22:53 UTC](https://discourse.nodered.org/t/state-machine-how-to-compare-numbers/71340/19 "2022-12-01T22:53:34Z")

</div>

I found limitations in node-red-contrib-state-machine when your states are numbers and you need a state \> or \< a certain number. If you add this in your parameter ‘\>10’ the block will interpret that this a string and not a number comparison.  
The JS code provided by dynamicdave was more flexible and straightforward.  
I also think that many, except electric engineers in general, do no understand the concept of FSM. That might be why the node is not so popular.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [15 December 2022 22:54 UTC](https://discourse.nodered.org/t/state-machine-how-to-compare-numbers/71340/20 "2022-12-15T22:54:14Z")

</div>

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.
