Giter VIP home page Giter VIP logo

node-red-contrib-persistent-fsm's People

Contributors

deancording avatar hufftheweevil avatar jlsjonas avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

node-red-contrib-persistent-fsm's Issues

Same message incorrectly gets emitted in scenario's using multiple state machines

I found a problem with this add-in where multiple state machines that all configure a non-zero initial delay end up emitting the exact same message on startup.

I created a reproduction scenario by creating three state machines across three flows, with an initial delay of 1, 2, and 3, all with a different persisted state. When re-starting the flows, all state machines emit the message that should only be emitted by the state machine I created last.

The problem appears only when initalDelay is non-zero, and seems to originate in this code in state-machine.js:

     ...
      } else if (statePropertyType === 'msg') {
        RED.events.on('flows:started', function () {
          msg = {}
          RED.util.setMessageProperty(msg, stateProperty, node.fsm.state)
          if (+config.initialDelay) setTimeout(() => node.send(msg), config.initialDelay * 1000)
          else node.send(msg)
        })

The 'msg' that's created here in the msg = {} statement seems to be created globally before the timeout ends. Therefore the message that's actually sent by all state machines across all your flows ends up being the same, being the one for the node that was initialized last. Suggest fixing this by replacing this by let msg = {}

State Machine - How to Compare Numbers?

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

And the configuration inside:

image

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?

Node does not save state when redeployed

I have created a simple automaton consisting of three states and three triggers. Everything works fine, as long as I'm just playing with it, the states switch, no extra messages are displayed. Everything goes as it should.
But if I'm not in default state and make a deployment, the node switches to default state, despite "Persist state on re-deploy" checkbox.
What I expect from the "Persist state on re-deploy" checkbox is that the node's state will only be reset when the entire NodeRED is rebooted. I have recorded a short video with a demonstration. The version of nodered is 3.0.2, node-red-contrib-persistent-fsm is 1.2.1.

https://mega.nz/file/zwBkHKxB#ct0z15SjTgHjQnQSVAMwyNdsqxM8gIXSnufx4oHJOyA

State not persisted on deployment

I use Node Red as part of Home Assistant. The node-red-contrib-persistent-fsm is amazing! It helps control many things like blinds and lights with very few buttons, as it keeps track of the state and can act intelligently with the next press on the same button.

This worked great until about two weeks ago. Suddenly, things started to act weird. For example, blinds started going into the open position in the morning. There was no change in the Node-Red flows at that time. I updated a few things (Home Assistant and Node Red itself), but I'm not sure how closely related that is.

I attach a quick screencast to demonstrate:

  • The state machine has two states: open / closed
  • The states are toggled on input
  • The option "Persist state on re-deploy" is enabled
  • On deploy, the state machine always returns to the initial "closed" state
state-machine-screencast.mp4

This is the flow export from this example:

[{"id":"bb4fd94092510052","type":"tab","label":"State Machine not persistent","disabled":false,"info":"","env":[]},{"id":"cbb840864cfb0a79","type":"inject","z":"bb4fd94092510052","name":"m","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"toggle","payloadType":"str","x":130,"y":120,"wires":[["1b3e44b669aa1d14"]]},{"id":"1b3e44b669aa1d14","type":"state-machine","z":"bb4fd94092510052","name":"Blinds","triggerProperty":"payload","triggerPropertyType":"msg","stateProperty":"payload","statePropertyType":"msg","initialDelay":"","persistOnReload":true,"outputStateChangeOnly":true,"throwException":false,"states":["closed","open"],"transitions":[{"name":"toggle","from":"closed","to":"open"},{"name":"toggle","from":"open","to":"closed"}],"x":290,"y":140,"wires":[["657d41f0b789875e"]]},{"id":"657d41f0b789875e","type":"switch","z":"bb4fd94092510052","name":"Action OPEN / CLOSE","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"OPEN","vt":"str"},{"t":"eq","v":"CLOSE","vt":"str"}],"checkall":"false","repair":false,"outputs":2,"x":480,"y":140,"wires":[["1ffbcc68a82b3c6d"],["030ab2f9181a1911"]]},{"id":"1ffbcc68a82b3c6d","type":"api-call-service","z":"bb4fd94092510052","d":true,"name":"Blinds OPEN","server":"f915e846.bc0e18","version":5,"debugenabled":false,"domain":"cover","service":"set_cover_position","areaId":[],"deviceId":[],"entityId":["cover.markise_terrasse_alle"],"data":"{ \"position\": 25 }","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":750,"y":120,"wires":[[]]},{"id":"030ab2f9181a1911","type":"api-call-service","z":"bb4fd94092510052","d":true,"name":"Blinds CLOSE","server":"f915e846.bc0e18","version":5,"debugenabled":false,"domain":"cover","service":"set_cover_position","areaId":[],"deviceId":[],"entityId":["cover.markise_terrasse_alle"],"data":"{ \"position\": 100 }","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":760,"y":180,"wires":[[]]},{"id":"f915e846.bc0e18","type":"server","name":"Home Assistant","addon":true}]

I'm not quite sure where to start debugging. Maybe I'm doing something wrong? Maybe the Node Red update broke something? Maybe the underlying data storage is no longer working?

Any help would be greatly appreciated.

Multiple initial messages following fsm node edit, due to incorrect removeListener call

To see the problem add a state machine node to the flow and connect it to a debug node.
Open the state machine node, add a state and a transition specification. Leave the Initial Delay at 0.
Deploy and note that the "start" task message appears in the debug pane.
Open the state machine node and add another task. Perform a Modified Nodes deploy. Note that two "start" messages are seen.
Move the debug node a little and Deploy again, again two messages are produced.
If the state node is modified again then the number increases.
Restart node-red and then only one message is seen.

I believe the cause to be incorrect removal of the flows:started event. If the line adding the event
RED.events.on('flows:started', function () {
is changed to
let f;
RED.events.on('flows:started', f=function () {
and the line removing it
RED.events.removeListener('flows:started', node.startup)
is changed to
RED.events.removeListener('flows:started', f)
then that appears to fix it. However I am no expert in this area so that may not be the correct way to fix it.

I am using fsm node 1.2.0, NR 3.0.2, nodejs 16.17.0

Transition error is not caught by Catch node

I configured a state machine node and added a Catch node to catch errors, but if I send it an erroneous payload the Catch node does not catch it. The error message does show in the debug log.
Is it intended that I should be able to catch it?
Using fsm node 1.2.0, NR 3.0.2, nodejs 16.17.0

Example flow

[{"id":"48923fbe9da4d810","type":"catch","z":"3e6e1c87317d6268","name":"","scope":["5ae741363f50a810"],"uncaught":false,"x":290,"y":580,"wires":[["6592204c93b6511e"]]},{"id":"6592204c93b6511e","type":"debug","z":"3e6e1c87317d6268","name":"ERROR","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":460,"y":580,"wires":[]},{"id":"5ae741363f50a810","type":"state-machine","z":"3e6e1c87317d6268","name":"fsm error test","triggerProperty":"payload","triggerPropertyType":"msg","stateProperty":"payload","statePropertyType":"msg","initialDelay":"0","persistOnReload":true,"outputStateChangeOnly":true,"throwException":true,"states":["start","going"],"transitions":[{"name":"Reset","from":"*","to":"start"},{"name":"Go","from":"start","to":"going"}],"x":310,"y":520,"wires":[["e7f3d459f828f671"]]},{"id":"c85a77d947810d2c","type":"inject","z":"3e6e1c87317d6268","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"Go","payloadType":"str","x":110,"y":520,"wires":[["5ae741363f50a810"]]},{"id":"0a25a7398acc3198","type":"inject","z":"3e6e1c87317d6268","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"Reset","payloadType":"str","x":110,"y":480,"wires":[["5ae741363f50a810"]]},{"id":"9fd5f57603dc8996","type":"inject","z":"3e6e1c87317d6268","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"Error","payloadType":"str","x":110,"y":580,"wires":[["5ae741363f50a810"]]},{"id":"e7f3d459f828f671","type":"debug","z":"3e6e1c87317d6268","name":"STATE","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":450,"y":520,"wires":[]}]

Persist state on re-deploy not working inside subflow

Steps to reproduce:

  1. Create a subflow
  2. Add a state-machine node and configure with states / triggers
  3. Save subflow and add to subflow to a flow
  4. Change state of state-machine through subflow
  5. Redeploy
  6. State is reverted to intial state

Strange interdependency of multiple nodes in one flow

Hi,

I created a flow with 2 state machine nodes. However, I see that the nodes create many messages during startup and even create messages for states they do not even have configured.
Does this library only support one node for each flow? Am I holding it wrong?

State machine breaks on numeric Trigger input

When serving a numeric trigger input, the code crashes with "TypeError: label.split is not a function" as it's trying to parse the input as a string label & split it (which is not a valid operation on a number)

use-case: counting number of taps within a short time (double-tap emulation) to control transitions (while protecting from invalid states & keeping track of the current state)

State machine sending message on flow deploy

Node Red 2.1.4
node-red-contrib-persistent-fsm 1.1.0

I'm using Node-Red via Home Assistant integration (10.3.0) on Raspberry Pi 3

I did some upgrades and one of my flows started sending notifications whenever I deployed any other flow (fully or partially), after some careful investigation I realized that the state machine started sending messages, I managed to recreate a very simple variant of my flow to present problem:

image

I use the Output Only On State Change option but my initial state is sent now, this is something that did not happen before upgrading.

I consider it a regression, if the output is only allowed on state change then sending the initial state would suggest that we switched state to initial from something else which is incorrect.

For those looking for a quick and dirty fix, you can add change node before state machine and add some constant value at the random, unused, field, then you can filter all messages after state machine, those without this field are not allowed to go futher - this way you only process the messages that triggered state machine in such case.

State machine node does not pass along correct payload output

After incorrectly assuming this was an internal Node RED node, I believe this is the node responsible for the State Machine node I'm using (Installed with Home Assistant).

Current Behavior

The state machine node does not pass along the correct payload output (when set to msg.payload). However, when leaving the setting blank the correct output is passed along.

Expected Behavior

Expected behavior is to correctly pass along the payload output or remove the requirement from the settings panel (i.e. allow the State Output field to be blank). Currently if leaving the field blank, node red will complain that the flow is not properly configured although the state machine node behaves as expected.

Steps To Reproduce

Steps to reproduce is use the following example flows, then inject the following nodes in order:

  1. inject "started_code"
  2. inject "entered_code"

In the first flow example (at the top), you'll see that the output is as follows:

2/17/2022, 3:39:57 AM[node: 3b5ce3c79e4f6d48]
msg.payload : string[12]
"started_code"
2/17/2022, 3:39:58 AM[node: 3b5ce3c79e4f6d48]
msg.payload : string[12]
"entered_code"

However in the second example flow, you'll see that the correct output (entire) object is as follows:

2/17/2022, 3:41:07 AM[node: 01eaa788477ab975]
started_code : msg.payload : Object
{ action: "started_code" }
2/17/2022, 3:41:08 AM[node: 01eaa788477ab975]
entered_code : msg.payload : Object
{ action: "entered_code", pin: "1234" }

Example flow

[{"id":"a882694fff3a7c97","type":"tab","label":"State Machine Bug","disabled":false,"info":"","env":[]},{"id":"bc8915c160d7d096","type":"state-machine","z":"a882694fff3a7c97","name":"","triggerProperty":"payload.action","triggerPropertyType":"msg","stateProperty":"payload","statePropertyType":"msg","initialDelay":"0","persistOnReload":false,"outputStateChangeOnly":true,"throwException":true,"states":["default","started_code","entered_code","reset"],"transitions":[{"name":"started_code","from":"default","to":"started_code"},{"name":"entered_code","from":"started_code","to":"entered_code"},{"name":"reset","from":"started_code","to":"default"},{"name":"reset","from":"entered_code","to":"default"}],"x":480,"y":180,"wires":[["3b5ce3c79e4f6d48"]]},{"id":"3b5ce3c79e4f6d48","type":"debug","z":"a882694fff3a7c97","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":650,"y":180,"wires":[]},{"id":"76c9300f2c217d66","type":"inject","z":"a882694fff3a7c97","name":"started_code","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{ \"action\": \"started_code\" }","payloadType":"json","x":110,"y":120,"wires":[["bc8915c160d7d096"]]},{"id":"06ae0dc1696f4521","type":"inject","z":"a882694fff3a7c97","name":"entered_code","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{ \"action\": \"entered_code\", \"pin\": \"1234\" }","payloadType":"json","x":110,"y":160,"wires":[["bc8915c160d7d096"]]},{"id":"adee97ad1c29fec2","type":"inject","z":"a882694fff3a7c97","name":"reset","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{ \"action\": \"reset\" }","payloadType":"json","x":90,"y":240,"wires":[["bc8915c160d7d096"]]},{"id":"a475d0265f50c707","type":"state-machine","z":"a882694fff3a7c97","name":"","triggerProperty":"payload.action","triggerPropertyType":"msg","stateProperty":"","statePropertyType":"msg","initialDelay":"0","persistOnReload":false,"outputStateChangeOnly":true,"throwException":true,"states":["default","started_code","entered_code","reset"],"transitions":[{"name":"started_code","from":"default","to":"started_code"},{"name":"entered_code","from":"started_code","to":"entered_code"},{"name":"reset","from":"started_code","to":"default"},{"name":"reset","from":"entered_code","to":"default"}],"x":480,"y":480,"wires":[["e533e96241f4c106"]]},{"id":"e533e96241f4c106","type":"debug","z":"a882694fff3a7c97","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":650,"y":480,"wires":[]},{"id":"9f5bc1591bab3d2a","type":"inject","z":"a882694fff3a7c97","name":"started_code","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{ \"action\": \"started_code\" }","payloadType":"json","x":110,"y":420,"wires":[["a475d0265f50c707"]]},{"id":"d075c62995f6e9f7","type":"inject","z":"a882694fff3a7c97","name":"entered_code","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{ \"action\": \"entered_code\", \"pin\": \"1234\" }","payloadType":"json","x":110,"y":460,"wires":[["a475d0265f50c707"]]},{"id":"74aa837fc903e414","type":"inject","z":"a882694fff3a7c97","name":"reset","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{ \"action\": \"reset\" }","payloadType":"json","x":90,"y":540,"wires":[["a475d0265f50c707"]]}]

Environment

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.