Send command from a binding?

For developing the iCalendar binding together with @AndrewFG i’d like to hear some architectural advice from more experienced dev’s. There was the idea that the binding could replace at least in some parts the oh1 caldav-command addon. However a compatible version would require that commands will be sent directly from the binding to other items outside the binding without the core rule engine.

This somehow breaks the concept of the rule engine. So the question is, if we should do that [1]. It gives the user much power by data but also destroy the border between the binding and the rest of openHAB.

Please point me somewhere if i’m thinking too complex and there is even a concept for such use cases.

Thanks in advance.

[1] i’ve not searched the API if this is even possible without greater hacks, yet

Have a look into the documentation of the Event Bus.

And you might be interested in the util class TypeParser too.

Maybe it is a good time to take a look on following thread: Flexibility of framework supplied types

Above thread brings idea of new types - inclusing one for a Schedule, Time or Date alone.
Per say sending commands (thus interacting with items) is reserved for rules. Your binding is getting somewhere else, which is still fine I guess.

Look at the EventPublisher#post - will allow you to post changes to other bindings. I used it extensively in the neeo io binding to allow the neeo remote to execute changes in any installed binding. Works very nicely

Bummer we are thinking about infusing new types - will make bindings like this nearly impossible to maintain since they need to be aware of the new types…

For the avoidance of doubt, we are NOT talking about introducing new types.

The plan is that this binding will parse iCalendar events, and when the events begin or end, the binding will issue commands to change the state of other Items in the system, via Subject_Item.sendCommand(Target_Value). We have identified two potential ways to do that…

a) Issue the sendCommand directly from within the binding.
b) Change the state of a “helper” Item; which triggers a user created rule; which issues the sendCommand in the rule.

We think solution a) may be neater, and easier for users; however we are not sure if the OH code owners will allow us to influence the state of other Items from within this binding.

PS as @damihe also says, we have not fully investigated if the OH api does even have a call interface whereby this binding could issue a sendCommand; so the question a) or b) may actually be an academic one :slight_smile:

Either I’m missing what you are saying or you’re missing what I’m saying :smiley:

EventPublisher is how you’d send commands to other items withing the system - see https://www.openhab.org/docs/developer/utils/events.html#send-events

Basically the “sendCommand” does the same thing as EventPublisher (I wouldn’t be surprised if sendCommand actually uses EventPublisher under the scenes to do the work - don’t have the time to look however).

No. I think I got what you’re saying Ok. I believe you are saying that a) it is possible for one binding to (effectively) sendCommand to other Items in the system (even if they belong to other bindings). And furthermore, I believe that people are b) saying implicitly that if it is possible to do it, then it is also allowed to do it. :slight_smile:

Hi @damihe I will do a quick hack and write some Java code today or tomorrow as a proof of concept (if that is Ok with you)…

1 Like

I’m not sure I understand the concern, either.
There are several existing bindings that can be configured to “go against convention” and issue commands to Items via channels, rather than the more usual state update.
Such commands appear on the OH event bus, just like a UI or rule issued command (and so obviously you can do the same things with them, like triggering some other binding with a channel linked to the same Item).

You might use this where the remote device is e.g. a control panel. User pokes a button, command arrives in openHAB. Just like a UI.
Switch someItem "my Light" {channel="knx:myTouchPanel" , channel="modbus:myLightRelay" }

For scheduler use, it seems reasonable that e.g. the scheduler service can command Item “alarmclock” on at 07:00.

However a compatible version would require that commands will be sent directly from the binding to other items outside the binding without the core rule engine.

I personally wouldn’t care too much on compatibility to an 1.x version as long as its functionallity could be reproduced with the new binding + rules. IMHO the binding should be rather kept simple.

To answer this it’s good to first define concepts. A binding is something that communicates with something external (in general) and communicates with openHAB through channels. Bindings are not allowed to directly talk to items and not access channels of other bindings. But this is purely a definition of a binding. Because the general concept is called an add-on. For example persistence is not a binding but an add-on. So I think we are talking about add-ons here, not specifically bindings.

So what can this be? I’m not completely familiar with how this intended to work, but it sound like a automation add-on, like a Trigger and/or Action. It’s possible to create a custom Trigger/Action and those can be configured to take an item as input/output. There are not a lot of add-ons, if you search for BaseTriggerModuleHandler only the hueemulation comes up. But in openhab-core there are more implementations that can give an idea. These automation add-ons would be completely compatible with the core rule engine.

As a replacement for CalDav-Command, this would not be using automation. I believe the specific functionality being referred to is to have a calendar entry send a command to an Item with data supplied in the description of the calendar entry when the meeting starts and ends.

Thank you all for this constructive discussion!

@AndrewFG, yes a quick PoC would be nice, the EventPublisher sounds like a great possibility to do that. It’s architecture is quite loosely coupled which is good in this case.

Yes the binding is now quite simple. However looking into the old addons’ voting thread there are many users of caldav-command. And it’s more flexible in a from user view understandable level than a big set of rules together with events-beginnings and ends.

However i want also to keep this addon maintainable - and i would like it if the addons would be later added to the official ones.

Yes, @5iver your understanding is fully correct. The binding will parse the contents of each iCalendar event looking for “Command Tags” which consist of a subject (Item name) and a targetState. At the beginning (resp. at the end) of the calendar event the binding will issue something like the following code…

    /**
     * @param tag 

     * Execute a sendCommand to the Item whose name is tag.subject, and
     * to change its state to the value in tag.targetState
     *        
     */
    private void sendCommandToOpenHAB(CommandTag tag) {
    	if (eventPublisher != null) {
	    	// TODO: we need to convert the tag.targetState String to a Command class  
	        Command command = null; 
	        ItemCommandEvent itemCommandEvent = ItemEventFactory.createCommandEvent(tag.subject, command);
	        eventPublisher.post(itemCommandEvent);
    	}
	}

As you can see from the comment in the code, I am struggling about how to convert the tag.targetState String to a Command object, so any advice here would be appreciated :slight_smile:

Done. I uploaded some files to your GitHub repo just now. It is not yet a full PoC since there are still three quite important methods that I have not yet been able to implement :frowning:

Today i’m not more able to look into code. Give me a bit time.

However, i’m really happy about the advice and the positive feedback. I think from non-technical side we can try an implementation after the PoC works.

You can see in such a way, but if you will take a look on MQTT 1.x -> 2.x migration topics are mapped to channels and things. It could send commands directly but for some reason it does not.
You either end up with multiple things, unaccepted architecture (see MQTT) or new type (s).
Be aware that some devices have a scheduling capabilities and drawing it on calendar widget would be helpful for users too.

Now I am confused. Most people here are saying that what we are proposing to do IS accepted (and therefore it does not require any new types). But you are saying the opposite. So is there any consensus on this? We want to follow the consensus, which is why @damihe created this post to discuss it.

In my perception what you do is fine, but final word will be said once you make a pull request. I am not eligible to accept these, I think other people in this topic are, but be aware that end decision can be surprising. You can end up with such conversation: https://github.com/openhab/openhab-addons/pull/1903#issuecomment-317404614 learning about dogmas and implied boundaries.

I expressed my concerns about clarity for developer here: Binding or Service ? Service Code Template. Even in this topic you can read that “Bindings are not allowed to directly talk to items and not access channels of other bindings”. My proposal for you is to not wait for consensus here but create [WIP] pull request and see what kind of feedback you will get from maintainers at github. Make it official that you want to send a command from a binding and wait for reactions.

Cheers,
Łukasz

1 Like

Hi @cweitkamp yes this EventPublisher seems definitely to be the way to go. We would use it based on pseudo- code something like that below. => So my “only” remaining question is how to instantiate the eventPublisher field in our class? – It says in your link “The EventPublisher will be injected via OSGi Declarative Services” – but what do I have to “declare”, in order to do that?

private EventPublisher eventPublisher;

private void executeCommandTag(CalendarEventCommandTag tag) {
    if (eventPublisher != null) {
        ItemCommandEvent itemCommandEvent = ItemEventFactory.createCommandEvent(tag.itemName, tag.command);
        eventPublisher.post(itemCommandEvent);
    }
}

Hi @daMihe I have now completed writing the new code (see https://github.com/openhab/openhab-addons/pull/6453) and except for the part “the EventPublisher will be injected via OSGi Declarative Services” its is ready to go. i.e. ready when you are :slight_smile: