State type is deprecated and will be removed in version 1.0

After checking this again, yes I am sure.

is and is not operators are equivalent to = and !=, but hold a stronger meaning of equivalence in the python language. entity-state = 0 implies a test against the value held in the entity state. entity-state is 0 implies a test for the computer memory space for entity-state and for the constant literal 0 being identical.

In practice, I suspect that the use of is and is not rather than = and != is to help us differentiate more easily between operators that logically can be applied to both strings and numbers, from those that can only be applied to numbers.

<, <=, >, >= (as Kermit reminded me) work with numbers, but fail most of the time with strings. Hence 10 > 2 returns true, but “10” > “2” returns false. In the update, in conditional tests, using one of the numeric operators ( <, <=, >, >= ) will

  • remove the option for a string literal [and boolean, regex]
  • automatically cast the entity state to a number just for the purpose of the test

is, is not will

  • provide options for number, string, boolean, regex literals
  • test the entity state
    • as a string against a string literal
    • cast to a number and test against a number literal

Specifically for your case of zone, which Home Assistant holds as a numerical count of the number of persons currently seen in the home-zone.

This is just for the Current state node, and I have updated to version 0.80.3:

  • The (deprecated) State Type I have set back to “string”, hence no up-front state casting will take place
  • The If State test is set to is and 09 number and literal 1
  • The entity state value remains as “1” throughout the node, and the output property field data contains the entity object with state value as a string “1”
  • The msg.payload property has been cast (only at the very end of the node-processing) to a number 1
  • The conditional If State test has, in this case, passed as true

In this case, the test, using a numeric literal, has auto-cast the entity string value to a number for the comparison test. The test is 1 == 1 and it works.

Notes:
It is possible to use a string literal for this test, so the If State test can be set as az string and 1 (no need for " ") and this works, since the test is "1" == "1"

I can’t say why your test is not working for you, but I suggest upgrading to the latest version since there have been a number of updates recently. You could also try using the string comparison, testing for is “0” since this (should) work just as well - HA holds the state as “0”, we don’t convert the state, and we can always test state is "0"

Extra points:

I have only checked the Current State node this morning, as I think that is one you refer to above.

No I have not tested for any of the other literal options J: expression, msg., flow., global., entity. My assumption is that each of these must return a number, for a numerical test. JSONata can return a number, msg.property flow.name and global.name can hold a number. Quite what happens for entity.name remains to be tested, but I would expect that both entity state values (the node entity and the conditional test literal/constant entity) are likewise auto-cast to a number for the test.

No I have not tested for the in and not in operators. These, inclusive and not inclusive tests, should apply to arrays (or sets or lists). Hence for Boolean tests, testing an HA entity with a state value of “open” or “closed” [cover] the inclusive test can be set as in ["open", "on", "yes"] or similar.

Using in and az 1, 2, 3 does appear to work, since the string “1, 2, 3” is treated (converted?) as an array, and the inclusive test runs. Hence it would be possible to easily test for no people or two people, but not just one person, being home as:

If State in az 0, 2

so you could also use in az 0 as your test

2 Likes

Thanks for another detailed and excellent explanation. Much appreciated! I upgraded to 0.80.3 (for some reason that wasn’t automatically done as part of the Add-On update to 20.2.3 last week), and now my conditional tests using “is” are working as intended.

Mind helping me with this one? This is the reqson I opened this topic…

No-one else???

Dealing with this stuff is impossible on just a phone, and I also needed to update the websocket nodes to the very latest version before doing anything further…

I cannot read the detail in your video - the picture is too small.

As far as I can see, however:

  • You are using the Events: state node.
  • You are using a cover entity.

I have tested this node with a cover entity type, again, and I can find no issue. The cover opens, and I get an event, the cover closes, and I get an event. All working with State Type set to ‘string’.

You may wish to consider:

All covers usually report a state value of “open” and “closed”, or perhaps “opening” / “closing” and “unknown”, which represent either the state of the cover, or the current action of the cover motor. Attempting to cast this to a number is not going to produce a sensible result. The python method returns NaN for strings that do not parse to a valid number. NaN is a value, just as true/false is, and means “Not a Number”, which can be translated to “the string you are attempting to convert to a number is not recognized as a number”. Indeed “closed” has never been noted as a valid number in any civilization on this planet. I can’t speak for other planets.

If you wish to cast the entity state to anything other than a string, then the Home Assistant Boolean set, which includes “open”, will return true or false after casting, and is of much greater use.

In terms of why you are seeing a difference when the State Type is set to “number” or to “string”, I can only assume that you don’t have the latest version. There was a bug in the first releases with the State Type deprecation, and this has now been corrected. As always, as for the most recent post, and as I said almost three weeks ago, and almost without having to say it again, you must always check that you have the latest version of the websocket nodes, particularly after a major change such as this where followup updates may happen for a week or two.

After that, the remaining potential cause relates to the Ignore state change events when: settings.

You appear to be using a cover integration that returns the percentage of cover. This is held within an attribute value. To be clear, the HA event bus will fire an event when any change to an entity state occurs (eg the cover goes from “open” to “closed”) but it will also fire an event on the event bus when any attribute value changed - even if the state value did not change also. This means that, if you run the cover from 40% open to 50% open, you will have an event on the event bus. The state will be “open” in both [or perhaps “closed” in both, depends on the integration] but the attribute value for percentage closed will change from 40 to 50.

In such cases, the settings for the Ignore state changes when are critical. If “Current state equals previous state” is ticked, then opening the cover just a bit will fire an event on the event bus, but it will not be passed on by this node.

You probably need to:

  • update to the very latest WebSocket nodes - 0.80.3 as of this moment in time
  • start with a fresh node, and leave State Type as ‘string’
  • untick your “Ignore state changes when” for “equals previous state” (and probably also for unknown)
  • run the blind fully up and full down

This should generate events at each operation of the blind.

Other than that, I don’t believe I can add any further value here.

Best wishes.

1 Like

Long story, thanks for the time, appricated. I still don’t get it. But… this worked for about 2.5 years without any issues… and now all of a dudden with the depreciation and changing string not anymore… what do I need to change to keep this working?

Try deleting the node in question, deploy, then drag a new one and re-set it up.

Already did, but that is. Is solving anything as the issue is clear… can even reproduce… see animation.

If you put it in a trigger state node instead of an event state, is there no output as well?

If I understood correctly (correct me otherwise):

This disables ability to compare strings. Equality operator for strings worked as expected.
Maybe such a need is not frequent, but not unusual at the same time.

Does it happen to save dumb users who cannot see a difference between 10 > 2 and “10” > “2”?

I suppose it will be still possible to achieve using JSONata… but man… why introducing behavior that is different from aby other programming languages?

What’s more important (again correct me if I’m wrong): it introduces inconsistency within NodeRed environment, isn’t it? such a comparison works now differently (implicit cast under the hood) from the equality tests in other NR nodes?

BTW, really appreciate Biscuit’s will and patience with providing all those explanation. especially because that change wasn’t introduced by him, and the part of audience are non-programmers.

Change is never straightforward, and particularly so when there is no apparent reason for any associated upheaval.

Your question has to be addressed to Kermit directly, however you can always go to his GitHub repository for this work. All the code is there, and there are active discussions and issue logs [as well as documentation and all the releases with release notes].

I note the following, recently raised issue, with a similar question. The answer may helpfully throw some light on the direction being taken with conditional tests [and the challenges being faced in doing so].

I note that this is an ongoing work, taking quite a bit of effort, and which has to be conducted around what currently exists, and the various future changes planned for Home Assistant, and for Node-RED.

Both Home Assistant and Node-RED expound a philosophy of ‘no-code’ (perhaps better, ‘low-code’ or ‘click and select’). Home assistant generates a peculiarity in that all entity state values are presented as strings, without a defined type. In a world where it should be just “click to select”, constructing a predicate-expression of the form

<entity-state-value> <operator> <expression>

using UI click-and-select becomes difficult given the nuances from the interaction between implied entity state type (is the entity-state a string, a number or a boolean?), the operator, and the “value to test against”.

The operator selection includes

  • is [test of equality]
  • > and < [test of order]
  • in [test of inclusion]

The inverse tests (is not etc) and the boundary variants (> and >=) are just small differences, so fundamentally we have just three ‘operator-groups’.

If the ideal situation is that the operator and the RHS expression govern the implied (automatic) type-casting required, then

For test is [equality]

  • string = string requires no state casting
  • number = number requires state casting to number, and also requires the RHS to be a number
  • boolean = boolean likewise requires state casting to Boolean, and the RHS to be a Boolean

For test > [order]

  • string > string requires no state casting
  • number > number requires state casting to a number, and also requires the RHS to be a number
  • boolean > boolean is only valid if you assume that TRUE and FALSE are ordered (which may be the case in some languages but not others)

Although a test string > string is “doable”, it is fraught with issues. I made a slipup a few posts ago over the “2” < “10”, but I have long suffered the challenges of string order comparison. In the UK post-code system, which is a string, “BR10 1AA” is order-sorted before “BR2 1AA”. Even addresses get order sorted badly on our first line “10 The Drive” and “2 The Drive” [numbers 1 and 10-19 come before 2]. Even equality can be an issue, since many users here will make the assumption that a cover entity state is “Open” or switch “ON” when HA insists on lowercase throughout.

Put simply, in a “click-and-select” world, the user should be guided to a choice from only the possible valid options, and perhaps here the best way to do this is to start with the Right Hand Side Expression (what we are testing against). Note that Home Assistant will only present entities in a drop-down selection list that have the correct platform, state or device class (eg the Energy Dashboard will not allow you to select invalid entities).

In short - should we allow users to perform any sort of order-conditional test on strings in any way? At least, using the UI click-and-select? A moot point perhaps.

JSONata

For any conditional test, the RHS expression can be something like msg.test, and it remains up to the user to ensure that the type of the value held in the message field is correct for the test operator being used.

For any test, the RHS expression can be JSONata. In terms of Node-RED, JSONata is actually the preferred processing language (rather than JS and function nodes), and is in-build throughout Node-RED core nodes.

JSONata can be used as an expression to compute and return any value for the RHS of the conditional test. This includes literal values also. JSONata expressions are evaluated, and any literal that is valid JSON will be returned ‘as-is’. Hence the JSONata expression

"12:34"

is evaluated, and returns just a string “12:34”. The same for numbers and Boolean.

String order comparison can be done reliably for well formatted string such as time “hh:mm:ss” with leading zeros and 24 hour clock. The same for dates in “yyyy-mm-dd” format.

Home Assistant holds entity attribute values such as

last_triggered: 2025-09-01T15:02:51.574988+00:00

which with a bit of JSONata code, can be stripped out to a value “2025-09-01 15:02”. This can be order tested by date and/or by time.

String order comparison can be done using JSONata, and perhaps given the challenges of lexicographic ordering, Kermit is indeed making a very sensible distinction between

  • easy - do it in the UI
  • not easy - do it in JSONata

Anyway - this is all well and good as a philosophical discussion but I had other things planned for this morning :laughing:

1 Like

As I said, I have tested a similar Events: state node with a cover entity arrangement and I cannot replicate your issue. What you say is happening for you is not happening for me, and for me it all works as expected.

I suggest that you check the Node-RED logs when you operate your blind, both with the node State Type set to “number” and again with it set to “string”. I also suggest that you check your current versions for HA, the Node-RED add-on, the WebSocket nodes, and for the Node-RED Companion.

You may have had this working for years, but casting a state string value “open” / “closed” to a number has just been generating a state value NaN. You are relying on HA generating a state event just for an attribute change only (which it will) but you have set your node to ignore state change events where the current state equals the previous state, hence the node would never respond to just an attribute change only, so I am unable to understand why it ever worked for you at all.

Sorry, but that is not my issue, I rely on another value from the entity. I could use it before but anyomore. I believe you can not replicate this as you must het similar cover entities on HA then. Do you have them?

I have some cover entities.

One integration generates a state change of the cover state value to “opening” on open [or to “closing” on close], then to “unknown” almost immediately after (it is not able to track the actual state of the cover so reports ‘unknown’).

Another integration generates a state change of the state value to “open” on any open, and to “closed” on fully closed.

Neither integrations have the ability to track percentage opening, which is what you are doing using a state-attribute. So I have set up a mock sensor cover, with both state value and an attribute value, which I can change as either the state value only, or the attribute value only, or both the state value and the attribute value at the same time.

As a mock-test: open cover from ‘closed’ 100% to ‘open’ 10%

Then, change to 40% by changing only the attribute ‘other’.

The Event: state node still fires, even with the state remaining as “open”.

The Event: state node does what it should - it generates an output message for the state event change caused by only the attribute (‘other’) changing from 10 to 40.

You can see that at this event, the fields for

  • last_changed
    • Time the state changed in the state machine in UTC time. This is not updated if only state attributes change
  • last_reported
    • Time the state was written to the state machine in UTC time. This timestamp is updated regardless of any changes to the state or state attributes
  • last_updated
    • Time the state or state attributes changed in the state machine in UTC time. This is not updated if neither state nor state attributes changed

change correctly for the updated (as the state-object has changed) but not for the changed (as the state value has not changed).

All working as expected.

I suggest that you check the Node-RED logs when you operate your blind, both with the node State Type set to “number” and again with it set to “string”. I also suggest that you check your current versions for HA, the Node-RED add-on, the WebSocket nodes, and for the Node-RED Companion.

I’ve got a strange one. I fixed around 80 such nodes and eliminated the warning messages. This one persists:

State type set to string… Deprecated settings hidden prior to deployment. No output fields set. It’s been this way for a few days through multiple unrelated reboots/restarts.

The flow works just fine and I know this error won’t hinder function. It’s just annoying.

I am aware that Kermit says that when the cause of the warning messages is removed and the flow deployed, these messages should go immediately. However my experience is that some can be sticky, even over reboots.

The warning messages each have click-points for edit / find / hide. If you hide an active warning message (there is still a problem in the node configuration) then the message is greyed out, and the display “show hidden” option works, in that all hidden messages can be hidden completely from sight, or displayed but remain greyed out.

I have just found that, fixing the issue and then subsequently clicking the ‘hide’ option on a message that has been resolved, but is still hanging around, makes it vanish altogether.

This [click on the message hide option] appears to work for both messages that are not hidden and then fixed, and also for messages that were hidden and then fixed.

I think the fix is

  • address the configuration issue (in this case, set State Type to “string”)
  • redeploy
  • if the warning message remains
    • click on the ‘hide’ option on the message

Tried this three times with the same node and it seems to work every time!

1 Like

I guess I should have tried this first. I just “fixed” it (easy) and redeployed, then sort of forgot about it and went about doing some other stuff outside of NR that involved at least 5-6 HA restarts… and meanwhile back in NR, that same warning stayed on.

Your suggestion above fixed it immediately. I’ve noticed your substantial contribution to this thread… I took some valuable info from it even before today. It’s appreciated!

1 Like

I was thinking I understand what is going on… but… I suppose I’m not.

If you look at screenshot. There is state change node, tracking a binary sensor.
I don’t use a built-in condition feature, but I set entity state to be converted to a boolean before reaching output’s payload.

Then look at debug: data confirms new state is ‘on’. Why was it not converted to true?

Below config of the HA server node.

You need to use as Home Assistant Boolean not as Boolean

There are now two different Boolean castings. as Home Assistant casts using the State Boolean list in the config node. as Boolean uses as standard test against the state string as ‘true’, or a number as not 0 only.

The option ‘boolean’ is new, and performs a casting of the entity state value to boolean using a more traditional procedure.

If the state string holds “True”, then this will be converted to lowercase first, then tested for an exact match to “true”, returning boolean true. The same for “False”.

If the state string holds a number, then this will be converted to a number, with 0 returning false and everything else returning true.

2 Likes

Thank you. For some reason I didn’t noticed Home Assistant Boolean when setting that.

Again, thank you for the prompt reaction.

I have also a lot of deprecated items.

But I don’t see what I need to change. Yes at the bottom you could set it to string to hide it. But what is the correct solution:

image