Skip to content

json binding

Jean-Michel DECORET edited this page Jan 19, 2016 · 2 revisions

Presentation

Sometimes in configurationSchema, you need dynamic content. This content must be generated by your plugin just before opening configuration form.

For example, you need serial port list. This list can change each time you plug an emulated USB serial port like FTDI. So you can't specify an exhaustive list of serial ports in your package.json.

You can use binding to do that.

There is two kind of source for binding.

"system" source

Many items can be ask to yadoms and are dynamic. For example the serial ports depend on the plateform and peripherals connected to. So it is impossible for a developper to provide a list of all serial ports for a user. In order to do that, the developper can use binding with system source. Yadoms have the ability to provide different information based on the "query" keyword.

The "system" type can be used in plugin configuration and in manually device creation.

Always in case of a serial port, the developper should use an enum to provide it to user using following configuration schema:

"SerialPort" :
{
      "type" : "enum",
      "name" : "Serial port",
      "description" : "The (virtual) serial port connected to the UPS",
      "values" : {"__Binding__" : {"type" : "system", "query" : "serialPorts"}}
},

Here is the list of all queries supported by system

query name description test URL
serialPorts Provide the list of all serial ports /rest/system/binding/serialPorts
networkInterfaces Provide the list of all network interfaces /rest/system/binding/networkInterfaces
networkInterfacesWithoutLoopback Provide the list of all network interfaces excluding loopback /rest/system/binding/networkInterfacesWithoutLoopback

"plugin" source

It indicates that the binding engine has to ask to the instance of the plugin to answer to the query.

The "plugin" type can be used only in manually device creation and not in plugin configuration.

It is formed like that in the package.json file:

"DynamicSection":
{
      "name": "A dynamic section",
      "description": "Example of section filled by 'test' method fo the plugin using binding.",
      "type" : "section",
      "content": {"__Binding__" : {"type" : "plugin", "query" : "test"}}
}

This section will be dynamically filled by the instance of the plugin. The plugin must catch the event yApi::IYadomsApi::kBindingQuery in its main eventHandler. The c++ code of the plugin look like:

while(1)
      {
         // Wait for an event
         switch(context->getEventHandler().waitForEvents())
         {
              ....
              case yApi::IYadomsApi::kBindingQuery:
              {
                 // Yadoms ask for a binding query 
                 boost::shared_ptr<yApi::IBindingQueryRequest> data = context->getEventHandler().getEventData< boost::shared_ptr<yApi::IBindingQueryRequest> >();
                 if (data->getData().getQuery() == "test")
                 {
                    shared::CDataContainer ev;
                    ev.set("HOUR", "1 hour");
                    ev.set("DAY", "1 day");
                    ev.set("WEEK", "1 week");
                    ev.set("MONTH", "1 month");
                    ev.set("HALF_YEAR", "6 months");
                    ev.set("YEAR", "1 year");
     
                    shared::CDataContainer en;
                    en.set("name", "Interval of the chart");
                    en.set("description", "Permit to change the interval of all the chart");
                    en.set("type", "enum");
                    en.set("values", ev);
                    en.set("defaultValue", "DAY");
     
                    shared::CDataContainer result;
                    result.set("interval", en);
     
                    data->sendSuccess(result);
                 }
                 else
                 {
                    std::string errorMessage = (boost::format("unknown query : %1%") % data->getData().getQuery()).str();
                    data->sendError(errorMessage);
                    YADOMS_LOG(error) << errorMessage;
                 }
                 break;
              }
            }
         }
      }

To manually test your plugin binding queries you can call following URI:

/rest/plugin/your plugin id/binding/your query

For example

/rest/plugin/4/binding/test

With that code, each time the configuration of an instance of this plugin is shown, the binding will ask to the plugin for the dynamic section content and show the full configuration.

Clone this wiki locally