The behavior of a method generating Commands

I see a behaviour I don't understand, is it a bug or by design? Here is an example, with learningMode set to true it behaves like written in the comments:

metadata {
    definition (name: "My Driver", namespace: "adriver", author: "Someone") {
        capability "Switch"
        
        // Attempt to generate Command entries
        generateLearningCommands()
        generateLearningCommands2()
    }

    preferences {
        generateLearningPreferences()
        input(name: "learningMode", type: "bool", title: "Learning Mode")
    }
}

def generateLearningCommands() {
    if(learningMode) {  // Using the value of learningMode
        log.debug "Shows in log"
        // These commands are NOT shown when learningMode = true, but the log entry above is generated
        command("eventStartLearning")
        command("eventSave")
    }
}

def generateLearningCommands2() {
    b = true
    if(b) { // Just using a bool
        log.debug "Also shows in log"
        // These commands ARE shown when b = true
        command("eventStartLearning 2")
        command("eventSave 2")
    }
}


def generateLearningPreferences() {
    if(learningMode) { // Using the value of learningMode
        // These preferences are shown when learningMode = true
        input(name: "myPreference", type: "bool", title: "My Preference")
    }
}

Any thoughts? What am I missing?

You can't generate commands dynamically at run time.

Ok, that is consistent with what I see, so I guess it is by design. But why? The variables are available judging by the fact the log messages work, so it would be possible to support dynamically generated commands with, presumably, little effort? Is this to enforce a standard for how drivers are implemented?

We have discussed both dynamic capabilities and dynamic commands in the past and do not have any current plans to implement support for this.
It isn't a simple change.

Ok, I see, thank you for explaining.
If you could just set an easy to access ID tag of the element it could be hidden in a reliable and easy way with CSS... As it is now, the CSS route is convoluted and feel way to much like a hack for it to be worth it. Just a suggestion, it might not be in line with your design goals to allow things like that anyway.

Why would it have to be hidden? You're going to be able to see the list of the available commands on the edit device page anyway. So, what difference does hiding them make?

In drivers which have a lot of extra commands possible for setup, debug etc, it would be good to not show them so as to not make it too cluttered. For example, for an RF receiver driver, in "learning mode" where the driver learns a code some buttons are needed, but once they have been learned and the driver is not in "learning mode", those buttons are not needed and have no function.

Perhaps you could consider a "service" app that creates devices and has this functionality instead? You can call any (non-private) method/function in your driver, even one that is not implemented as a user-facing "command," from such an app. The "buttons" in a driver aren't really intended as a full user interface, just a way for a user to manually execute commands (and check current attribute states, etc. from elsewhere on the page) if needed, often for troubleshooting or testing a new device. That is why staff push Hubitat Dashboard or similar solutions as the best option for users for manual control or monitoring of devices*, plus the app UI framework is more complex and allows you to create dynamic (or any) pages.

*something you could consider regardless but particularly if an app is overkill for this use case as well :slight_smile:

I've considered the "service" app route, I'll probably add that as well, though personally, I prefer to have this particular functionality inside the driver as well. What I'm asking for is the flexibility to be able to do what I want without reverting to "hacks" or having to use a different way of doing things (like doing this from an app).
Dashboards are still not flexible enough for what I want to spend time on. It works fine for lights/presence and some (not all) sensors as well as some other more advanced use-cases with cameras.

But see, that's not how drivers work. You can't define commands dynamically. So, the commands in the driver are the commands. Period. There's no reason to hide anything because there is no learning mode.

I want them to work that way, and if I could hide the commands when they are not needed, I would want to. Having the possibility and the flexibility is what I'm looking for. In my drivers for IR/RF there IS a learning mode, and it makes more sense to have it there than in an app, at least for now, and probably even when I do get around to making an app that can ALSO do it. It's about having choices.

But you can't. Do you understand that? It doesn't work that way and it's not going to work that way. Why should Hubitat change for you? It was working fine LONG before you showed up less than 2 months ago. Maybe you should learn how the system works rather than trying to change it.

Look, I don't understand your attitude, not at all. I'm looking for constructive feedback. Such as WHY this would not be a good thing, or WHY it would be a good one. Or anything else that is constructive.

I do want this feature, but, will I send a direct e-mail and ask for this to be added in the future, very unlikely. I bring it up here, because it is something I want and it interests me to see if there is a community response and others that also see a need. Will I get this feature? Probably not. Is it the most important to add? Very unlikely. It doesn't even enter my own Top-10 of features I wish Hubitat would implement to make it easier/better to develop drivers and apps. Most of what I want that is on my Top-10 has been discussed and requested by others already, and they are probably much more likely to be implemented since they are truly important for many developers.

1 Like

Don't mind him - he is just "that way" when posting sometimes. Why? Only he knows. But he is also an excellent resource, and really helpful most of the time, too. So - :man_shrugging:

I completely agree with you, for the record. I would LOVE the ability to hide commands/collapse sections of command in a driver.

Same with preferences, actually.

There are some custom drivers (most TV drivers are a good example) with DOZENS of commands exposed, and it is a honking mess for new users to wade through. But at the same time, the commands are useful and shouldn't be removed from the driver either.

I doubt it will be added, as Hubitat seems resistant to improving the UI much. So while I won't hold my breathe, I do think it would be a welcome feature.

1 Like

this has been discussed, along with preferences.
While we don't have any immediate plans to implement this, we understand the need and benefit of this.
This is much different than dynamic capabilities and commands, this is mostly UI work with a little back end schema to support it.
True code driven dynamic capabilities requires much much more platform work.

Much can be done by creating a parent stub device that's bound to the actual physical device, then via code or user preferences create composite child device(s) using the selected capabilities.
While the parent's capabilities aren't changing at run time, the composite children can.

1 Like

Yes, I've started to realize that...

:+1: :slight_smile:

At least with Preferences, I can have a boolean value which when set makes other Preferences show. This makes things a lot easier to use for the user, for sure.

Really do hope you could do this, or at least set a useful ID on the parent div of "tileContainter-XXXXX-Y", like "tileOuterContainer-XXXXX-Y"...
But yes, more than just an ID tag would make it usable for more devs as well as more robust.
With hope for a swift implementation of this feature, thank you for your patient replies!

Yes, absolutely, working on stretching that as far as I can in an upcoming driver...

I agree with you but for different reasons. :grinning:

2 Likes

:laughing:

Before this thread goes further into the weeds, the OP's original suggestion has been pretty well answered. Time to move on....

2 Likes