How to ignore the string item if its UNDEF

I hope that’s not too much to ask from good old DSL engine, but can I omit using either of the strings if their state is UNDEF?
So, if I do not receive the artist, currently my KodiSummary string item is updated to: “UNDEF - Songname”
I would like it to be just “Songname” or even “- Songname” is acceptable

rule "Kodi Now Playing Summary"
when
    Item myKodi_title changed or
    Item myKodi_artist changed
then
    KodiSummary.postUpdate(myKodi_artist.state.toString + " - " + myKodi_title.state.toString)
end

I guess I could do

rule "Kodi Now Playing Summary"
when
    Item myKodi_title changed or
    Item myKodi_artist changed
then
      if(myKodi_artist.state != UNDEF) {
        KodiSummary.postUpdate(myKodi_artist.state.toString + " - " + myKodi_title.state.toString)
       }
      if(myKodi_artist.state == UNDEF) {
        KodiSummary.postUpdate(myKodi_title.state.toString)
       }
end

under the assumption that I don’t care about the cases where title is UNDEF (which is true)

Your code works, but a better way to write it:

rule "Kodi Now Playing Summary"
when
    Item myKodi_title changed or
    Item myKodi_artist changed
then
    if (myKodi_artist.state == UNDEF) {
        KodiSummary.postUpdate(myKodi_title.state.toString)
    } else {
        KodiSummary.postUpdate(myKodi_artist.state.toString + " - " + myKodi_title.state.toString)
    }
end

To add something:

rule "Kodi Now Playing Summary"
when
    Item myKodi_title changed or
    Item myKodi_artist changed
then
    var String strSummary = myKodi_title.state.toString

    if(myKodi_artist.state != UNDEF) 
        strSummary = myKodi_artist.state.toString + " - " + strSummary

    KodiSummary.postUpdate(strSummary)
    )
end
2 Likes

Great application of the 1-2-3 Design Pattern :smiley:

The only addition I can make here is it’s possible that the title or artist Item has changed since the rule was triggered (unlikely) or one of the Items changed but the other hasn’t changed yet (more likely). So you might need to add some logic to handle that.

The most straight forward might be to use a timer to wait long enough for both to have changed before updating the summary.

rule "Kodi Now Playing Summary"
when
    Item myKodi_title changed or
    Item myKodi_artist changed
then
    val timer = privateCache.get('timer')

    // If there already is a timer running, reschedule it
    if(timer !== null && !timer.hasTerminated) {
        timer.reschedule(now.plusMillis(500))
    }
    // Create a timer to wait half a second before updating the summary
    else {
        privateCache.put('timer', createTimer(now.plusMillis(500), [ |
            var strSummary = myKodi_title.state.toString
            if(myKodi_artist.state != UNDEF)
                strSummary = myKodi_artist.state.toString + " - " + strSummary

            KodiSummary.postUpdate(strSummary)
        ])
    }
end

So let’s say a new media starts playing and both the title and artist change. Let’s say the rule triggers first for the artist. The above will wait up to half a second for the title to change before updating the summary Item.

You can experiment to see the minimum reliable amount of time to wait.

Finally, I’ll mention that if you are using MainUI to display this summary, you might be able to eliminate this rule entirely and use a custom widget instead. MainUI lets you combine multiple Items into one widget. For example Mediaplayer Now Playing and Control shows artist, media title, and lets you control the playback (combines five separate Items) in one list Item widget.

Would letting it simply update twice be that bad? It’s certainly most simple, and simple is good.

Anyway, for the “wait” strategy, I understand the OP is only interested in RulesDSL, but I’d like to show how simple it is in JRuby.

rule "Kodi Now Playing Summary" do
  changed myKodi_title, myKodi_artist
  debounce_for 0.5.seconds # just add this line to make it wait and not run repeatedly
  run { KodiSummary.update "#{myKodi_artist.state&.+ " - "}#{myKodi_title.state}" }
end

Explanations:

  • The &. is a null safe operator. It only calls the next method + if the state is not nil.

    In JRuby, if the state is an UnDefType (NULL or UNDEF), Item.state returns nil, which is handy to use in strings in such situations, because nil turns into blank when interpolated. You can still check using Item.null? and Item.undef? if you must know exactly.

  • debounce_for will cause the rule to wait until there’s X amount of time had passed without any new events, and then only executes the rule once, so in this case, the KodySummary will only get .update once.

If you think the &.+ is a bit too esoteric, you can still do it the “traditional” way.

rule "Kodi Now Playing Summary" do
  changed myKodi_title, myKodi_artist
  debounce_for 0.5.seconds
  run do
    summary = myKodi_artist.state ? "#{myKodi_artist.state} - #{myKodi_title.state}" : myKodi_title.state
    KodiSummary.update summary
  end
end

There’s not enough information to say one way or the other. We don’t know what this summary Item is being used for. If it’s just display then probably not. It it’s driving some automation, maybe.

it’s just displayed on the sitemap, and if nothing is playing then its hidden.
Thanks for the tip about mainUI and showing it in the widget without any rule, will make a mental note.
I haven’t made the leap to completely move over from the old sitemap. I’ve built semantic model, so I have all my lights, ac, temp/hum sensors etc, but haven’t migrated all the multimedia controls, need some time to come up with all the buttons, widgets and so on.

Definitely look at the marketplace. There are tons of media related widgets posted there which you can just install and use.

I saw some nice multi button widgets or whatever objects, so it will probably eventually look much better then the current sitemap that has a bunch of switches, each in separate line for each switch item (like power on tv, avr, projector).

And for wall builtin displays (tablet like) what is popular nowadays? :slight_smile:
habpanel, or MainUI ? Some custom site/dashboard, or just keep it simple and show the overview page? :slight_smile:

Mostly MainUI I think. Unlike HABPanel MainUI is responsive (i.e. resizes and flows reasonable on different sized screens).

I suspect for a tablet/wall display a custom page is used.

I personally have the most common controls/statuses shown on the main overview page and then use the Locations/Equipment/Properties tabs for everything else.

Note that Lights, Battery Statyus, and Services Status dynamically adjust as I add Items and Items change states. For example, if I toggle “tis the season” a bunch of smart plugs will appear which control the Christmas lights. The battery widtget only shows those battery Items below 35%. The service status widget shows those home automation related services which are offline only.

All three of these are posted to the marketplace.

The garage doors widget shows the open/closed status of both doors, lets me trigger the operners, and shows the garage camera all in one widget. The other two are just standard widgets.

I’ve not spent a lot of time on making this look pretty as I’m pretty much the only one who uses it and mostly use it from my phone (where there’s only one widget per row).

For everything else I use Location tab for the most part unless I want to compare all the temps or something like that.

1 Like