The following is a proposal to change the binding string format in openHAB to make it more standard, readable and easier for binding implementers. I know that this is likely to be a contentious suggestion since it does change the binding configuration, and it may be one for ESH/openHABv2, but I thought I’d throw it out there in case anyone had any thoughts :) I personally think it would be great to get a roadmap started for these projects so that people can see what the future holds and work towards its implementation.
Overview
This outlines some proposed changes to the current binding structure within openHAB. It does not change the core binding structure, and in fact should make bindings easier to implement. The aim is to make it easier for binding implementers, and for users to configure items.
While the current use of binding configuration strings provides a flexible format to support item configuration within the binding, it is not standardised across bindings, and is difficult to implement within a configuration GUI. Such a GUI, or it’s backend, would need to produce the binding strings which would be difficult given their non standard nature. Additionally, these binding strings then need to be deconstructed within the binding - not a difficult task, but still one that needs to be implemented.
The proposal outlined here is to standardise the string format, and pass a dictionary of configuration items to the binding. This removes the task of deconstructing the binding string from the binding, and standardises it by putting it within the item provider.
If used with the GUI configuration proposal, which would allow bindings to provide information on their status, including detection of new devices, a semi automated (man in the loop) system can be devised to detect new devices and add them to the openHAB configuration.
Detail
Currently the GenericItemProvider reads the items from the model, and dispatches the strings in full to the binding along with the item name. Within the binding the string is deconstructed and each component processed accordingly.
The binding string format within the model would be changed to a JSON format (other formats could be used, however JSON provides a simple way to define structures in a human readable format). The binding string would then include the argument name as well as the parameter (eg “Direction”:”OUT”). Within the GenericItemProvider, this JSON string is parsed into a dictionary, and then passed to the binding for processing as before.
Examples of an existing item binding string versus a new item binding string -:
{ snmp=“<[192.168.2.111:public:.1.3.6.1.4.1.4526.11.16.1.1.1.3.1.2:10000] }
Becomes
{ snmp=“direction”:”IN”,”address”:”192.168.2.111”,”community”:”public”,”oid”:”1.3.6.1.4.1.4526.11.16.1.1.1.3.1.2”,”update”:”10000” }
The naming of arguments is largely up to the binding author to choose, however it may be appropriate to specify some commonly used arguments globally to standardise where possible. This again makes it easier for the users to write the strings.
BindingConfigReader
/**
* This method is called by the {@link GenericItemProvider} whenever it comes
* across a binding configuration string for an item.
*
* @param context a string of the context from where this item comes from. Usually the file name of the config file
* @param item the item for which the binding is defined
* @param bindingConfig the configuration string that must be processed
*
* @throws BindingConfigParseException if the configuration string is not valid
*/
public void processBindingConfiguration(String context, Item item, String bindingConfig) throws BindingConfigParseException;
Becomes -:
/**
* This method is called by the {@link GenericItemProvider} whenever it comes
* across a binding configuration for an item.
*
* @param context a string of the context from where this item comes from. Usually the file name of the config file
* @param item the item for which the binding is defined
* @param bindingConfig the configuration string dictionary that must be processed
*
* @throws BindingConfigParseException if the configuration string is not valid
*/
public void processBindingConfiguration(String context, Item item, Dictionary<String, ?> bindingConfig) throws BindingConfigParseException;
I understand that this does mean changing all bindings and therefore may not be popular. However the change (to the binding at least) is quite small and I think it would significantly enhance the system. It’s easier for users to understand as the binding string reads in a more understandable way and it’s more flexible since the binding author can add more parameters without the constraint of putting parameter ‘x’ in position ‘y’. It’s also simpler to implement for the binding authors.
Of course, there’s nothing to stop bindings doing this now, and if we look at the zWave binding, this is very similar to what is done there (zwave=“<nodeId>[:<endpointId>][:command=<command>[,parameter=<value>][,parameter=<value>]…]”). Effectively, this proposal is to standardise on such a system to allow openHAB to grow…
It’s probably also worth adding that it’s probably possible to support both systems in order to ease the transition - old bindings would still work, but new bindings should be written to use the new system. Again, I’m happy to look at this if the feedback is positive…