Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Serverside datasource eval #458

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from

Conversation

kvolden
Copy link

@kvolden kvolden commented Nov 9, 2017

Sometimes, a usermodule would benefit a lot from being able to programmatically generate the options of a select field in the module's config – both when editing the configuration of and instance, and when creating a new instance. In some cases, it's possible to do this through the postRender functionality, which allows the developer to pass javascript for the alpaca form that is run client side when the form has rendered on the user's screen. It can also be possible in some cases to use the "click" and "onFieldChange" attributes to pass a function as text in module.json, which is executed on the element's click and onFieldChange events respectively.

But this is sometimes not a good solution, as the client side script is bound to the client scope (no access to z-way internals not provided by the API), suffers potential lack of access to the z-way local network, and is functionally limited. It also suffers from the pains of cross browser support. Although it's usually possible to create workarounds, these will often have to be awkward for both the developer and the user – for the developer because of the need for a lot of extra code, and for the user because of the frequent need to instantiate the module first, and then go back into the new instance's settings to do changes.

The change of AutomationController.js in this pull request implements the exact same approach that is found in zwave-smarthome -> app/services/services.js -> replaceModuleFormData() for translating text to functions for client side evaluation, except that it replaces the text with the (server side) evaluation of this function.

The reason why it should be evaluated on request, and not on module load, is that whatever the function generates could depend on some state that changes over time. This way, it is evaluated both on showing the config when instantiating new module instances and when editing the config of existing ones.

In use, the options section of module.json, in its simplest form, could look like this:

"options" : {
    "fields" : {
        "serverside_gen" : {
            "label": "Server side evaluated options",
            "type": "select",
            "dataSource": "function () {return ['alt_1', 'alt_2', 'alt_3'];}",

This example is nonsensical in its simplicity, of course. A more realistic example, which is also a use case of mine, is to generate a list of physical devices. Which could look like this:

"options" : {
    "fields" : {
        "physical_device" : {
            "label": "Physical device",
            "type": "select",
            "dataSource": "function (){ds = {}; for(var key in zway.devices){var name = zway.devices[key].data.givenName.value; ds[key] = name ? name : key;} return ds;}",

@kvolden kvolden changed the base branch from master to develop November 9, 2017 19:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant