Virtual Item - String - Default Value

That rule could look like this (untested):

rule "Set Default Values"
when
    System started
then
    Thread::sleep(10 * 1000) // let persistance finish restoring a few seconds

    if (Virtual_String.state == NULL) Virtual_String.postUpdate('Default value here')

    // repeat 'if' for other items
end
2 Likes

Hi @rtvb, I do not like all those “delays” ;-( As far as I could see, onve this solution is the only one, it points to something not well designed … I’m really missing ability for default values in OH…

openHAB Items are first and foremost variables representing the reality, often by being bound to a Binding channel. If you think about that you’ll realize that a “default/initialization value” is not something meaningful in the design of openHAB. Besides that, technically “NULL” is the fixed initialization value.

Let’s look at an example: A Switch Item bound to a lightbulb can either be ON or OFF. If the system is rebooted and hence can’t know about the state of the bulb, NULL is the only valid value the Item may have.
Now with that out of the way I agree that for “virtual items” the situation is a bit different. You can either restore it from persistence or set it in a rule. Both paths depend on the way the Item is logically related to reality. Once again a fixed initialization value doesn’t make much sense here.

What I’m basically trying to say: While in your very specific case a initialization value may make sense, it would be a design error for 99% of Items.

I do not fully agree that an Item is bound to an exisiting device only.

I use a lot of Items for storing parameter settings and proxy Items

What I have done to solve this problem is:

  • define presistence
  • define item (which is uninitialized on this step)
  • have a special rule which I trigger manually to set one time a value
  • after that the presistence do the job

Agree with @HomeAutomation

I can understand items as variables first fo all. If you declare a variable, you have chance to set the initial value of it in any programing language.
It would not make sence for 99% variables. But ther are variables that needs it / makes code cleaner / easier to maintain.

As items are variables and rules functions operating with them, this is missing option IMHO, combined with fact there is no defined startup order of rules/items/persistence forces you to do this “delays” workarouds for al items that does not represent real world object state, but some internals states, as @HomeAutomation mentioned, maybe I’m missing something?

This whole discussion is going to get philosophical.

We can look at Items in one of two ways (there are more ways than this but let’s choose two to focus the discussion).

  1. Items represent the real world (@ThomDietrich’s position I think). In this philosophy, Items should have some sort of relevance to the physical or logical home automation state. As such when OH comes up an Item should properly be initialized to NULL until such time that the real world device or service provides an update to that Item.

In this philosophy, an Item should only ever reflect the real world state of the device or system and if that is unknown the Item should indicate that it is unknown (i.e. be NULL). Rules and sitemaps should be written to behave and reflect that the states of these Items are unknown. And this means setting Items which are just configuration parameters (e.g. target temp for HVAC) is best handled using a System started Rule and/or restoreOnStartup because it makes no sense 99% of the time to set a default to an Item that actually should correspond to something in the “real world.”

I’m pretty sure this is the philosophy ascribed to by the maintainers

  1. Items are just variables. Items are just a convenient way to store variable information. As such we should be allowed to provide them with an initial value and treat them like any other variable in a programming language.

In this philosophy, an Item does not necessarily represent anything in particular other than state which is needed by one or more Rules or Sitemaps.

Even though I don’t necessarily code my system this way. I operate under the assumption that it is unlikely that my OH will be down for an extended period of time so I assume the real world state of my Items is unlikely to change while OH was down and therefore I can trust the restoreOnStartup state in my Rules. I don’t have anything automated where if my Rule is wrong it will cause something to happen if my assumption proves false (e.g. my lights may flash).

But I do this fully aware that I can’t necessarily trust the state of my Items. It would certainly be more consistent if I let my Items be NULL and just deal with that as appropriate in my Rules. In some cases this may make it simpler as I wouldn’t have to reschedule Expire binding timers on Sytem startup to set my Items to NULL after a certaion amount of time without an update.

I’m not sure what, if anything this adds to the conversation except to say that “I can understand items as variables first of all” is not necessarily a correct interpretation of the intent of Items.

I wonder if a binding that provided an initial value to an Item would be accepted. I’m thinking of something akin to the Expire binding that all it needs to do is postUpdate the value in quotes to the Item on startup. I’m not sure how that would work for a 2.x verison binding though.

Number TargetTemp { default="20" }

I’ll end with this that I wrote in response to this and other similar posts:

I’ve helped some users come up with some elegant solutions to some problems using approach 3.

Thank you @rlkoshak for long comment - I can deal with null, / undefined in my rules, that’s true. I’d also need to count with option that the rule will be executed in not defined order to persistence restore, so there is second volatility I need to cover… When you want to implement e.g. heater status icon with “manual” option switch (if you switch to “Mannual mode”, you can control the heater manualy) and let this be persistent, the rules for this will grow 2-3times because of that check logic only. I just tried to find way if there is simple way to let OH populate item in order “system default values” -> “persistence restored = last known value” -> “state managed by rules + real world changes”. That order would help me a lot for making rules clean and maintainable. I like the Number TargetTemp { default="20" } example, do we know when this value will be postUpdated to the item please? If before persistence restore and rules engine load, that would be great.

Since it is only a half-baked idea there is no answer to this. It will all depend on whether or if it is possible for the binding to know when OH is restarting/reloading and initializing the Items and whether it is possible to delay the restoreOnStartup somehow. I’m skeptical that would be easy of even possible. If it were, there wouldn’t be the problem with rules running before restoreOnStartup in the first place.

Thank you @rlkoshak, I’ll enhance DSL to allow me this and let OH load item with default value at items-loading time

It isn’t strictly a DSL issue. You will have to modify the ESH core as well.

I know, I’ve enhanced it before for instance for matching regexp item names in rules

@HomeAutomation and @jan.kadlec are you sure that you read and understood my comment? Your answers do not sound like it :confused:

Besides making a strong point for “don’t initialize Items” I still see a place for initial values. @rlkoshak the default binding idea could be something (I’d call it initialize, default is misleading). You could probably quickly derive it from the expire binding and no one is stopping you from adding it to the Eclipse IoT Marketplace. :wink: I would use it to get rid of my “System started” rules

@ThomDietrich I think I have understood, but I do have more types of items than light bulbs ;-( I can see usefull links from @rlkoshak, workarounds, none did fit to my usecase - if the system boots first time - let items controlling manual switches (and similar items like hysteresis direction values) publish with factory defaults. When system reboots (it’s quite often due to power cuts, electricity maintanance) it should restore to last values, that humans touched - otherwise it’s anoying in long term. If you can advise me how to achieve this behaviour in asynchronous / random order when loading items / rules / persistence please?

I’ve read that you do not use restoreOnStartup at all, how do you solve some switches like “Winter/Summer”, maintanance flags, etc?

Thank you for reply

I’ve read that you do not use restoreOnStartup at all

By now there is actually one instance where I do -for maintaining my apartment-wide heating mode.

All you are asking for can be solved. Maybe a few more examples will help you find your own solution:

All in all my system is fully functioning and real-world-synchronized after around 5 minutes. In that time no wrong actions are executed or wrong states shown in sitemap. If a Binding or device is not working, I’ll become aware oft that through the sitemap error elements.

I hope this clarifies some things! Otherwise please don’t hesitate to ask.
Enjoy!

3 Likes

I don’t know when I’d get a chance to work on it, but it would be an excellent choice for a first binding for someone to code up if anyone wants to run with this before I get a chance to code something up.

I’m not sure how it would work as a 2.x version binding. It seems awkward to have to create a Thing and then link Channels of that Thing to Items. But as a 1.x version binding, it leaves out the growing population of UI only OH users. but if we solved this for an initialValue binding then perhaps the same would work for Expire 2.x.

Reviving this old topic - I also would love to have an “initialize” or “default” binding as described above

Item
String AStringItem { initialize=“xyz” }

Has someone created something like this?

Every Item already has an easily detected default state (NULL).
Outlined above are several ways to work around that, if you want something else.

Not generically, but my Scripted Automation implementation of the Time of Day Design Pattern implements something like this. [Scripted Automation] Multi-day Time of Day Library

I’ve been deciding whether to extract this and make it generic. I’m hesitant to do this though because I fear it will be used in less than ideal ways. NULL and UNDEF are states that should be embraced and used, not avoided at all costs. But I also recognize there are times when you need to boot strap the state of an Item when it’s first created.

EDIT:

I’ve not tested this but it’s simple enough that it should work.

from core.rules import rule
from core.triggers import when
from core.metadata import get_key_value,remove_metadata
from core.utils import postUpdate, post_update_if_different

@rule("Initialize configured Items",
      description="Updates Items with an initialization value",
      tags=["init"])
@when("System started")
def item_init(event):
    """
    Rule that triggers at System started and populates Items with an initial
    value. The initialization value is defined in metadata with three key/values.
        - value: value to send update the Item to
        - override: whether to update to this value even if the Item already
            has a value. It's an optional key and should be either absent,
            "true", or "false"
        - clear: whether to delete the metadata once the Item is updated. It's
            an optional key and should be either absent, "true", or "false"

    For example:
        - { init=""[value="ON", override="true", clear="true"] }: Initialize
            the Switch Item to ON whether or not it already has a value and then
            delete the metadata.
        - { init=""[value="123,45,67"] }: Initialize the Color Item to the value
            only if it is NULL or UNDEF.

    Limitations:
        - The clear option only works for Items not created through .items
            files. For Items defined in .items files, you must manually remove
            the metadata or else it will get reloaded next time the file is
            loaded.
    """

    for item_name in [i for i in items if get_key_value(i, "init", "value")]:
        value = get_key_value(i, "init", "value")

        if get_key_value(i, "init", "override") == "true":
            post_update_if_different(i, value)
        elif isinstance(items[i], UnDefType):
            postUpdate(i, value)

        # only works if Items are not defined in .items files
        if get_key_value(i, "init", "clear") == "true":
            remove_metadata(i, "init")

I’ll probably submit it to the helper library at some point. But I’ve already a bunch awaiting merge so I’m holding off submitting new ones right now.

Hi @rlkoshak
Have you submitted your idea?
thanks

No, not yet. All my PR’s are still awaiting review and merging so I’m waiting for that to happen first.