Just had a few spare minutes, so I quickly built this simple flow. Can you check if it works for you?
[{"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"]]}]