Dear Community User! We have started the migration process.
This community is now in READ ONLY mode.
Read more: Important information on the platform change.

register-method-how-to.png

How to provide API in the Data Layer for your app

nickH
Community Moderator
Community Moderator

 
Introduction

This how to blog shows how easy it is to provide a API with a custom app on ctrlX OS. Just provide a interface in the ctrlX Data Layer and it is accessible by multiple ways. The ctrlX Data Layer has a built in REST API, therefore by providing your interface in the Data Layer, it is already accessible via REST. In addition, by just installing the OPC UA Server App it will also be available in OPC UA. And of course the interface in the Data Layer is accessible by all the other Apps running on the same device by Data Layer Access (for example from Node Red App or PLC App).

There are many samples (in different programming languages) in the ctrlX AUTOMATION SDK, which show how to provide data in the ctrlX Data Layer. This how to uses the C++ sample "datalayer.register-node" from the SDK to start, but modified it a little. In addition to just providing variables to the ctrlX Data Layer it is also possible to provide methods (or programs). This is defined in the metadata of the Data Layer Node. Its also possible to use scopes in the ctrlX Data Layer to restrict the access to the nodes provided for specific users.

The small example, which you can find attached provides one method in the ctrlX Data Layer (path: sample-cpp-registermethod/sqrt) which in case a client performs a write, calculates the square root. It also adds a scope to the ctrlX Data Layer, which can be used to restrict the access on this method for users.

Find more information
Prerequisites
  • Find the attached sample code at the end of this article.
  • Build it using the V1.20 SDK and App Build Environment and place it besides the other C++ samples at ctrlx-automation-sdk/samples-cpp. (see how to build a snap of the SDK)
  • To test the it install the snap on a ctrlX CORE (virtual) V1.20
See the output in the web interface
Try out the sqrt method in the Data Layer

Data Layer path: samples-cpp-registermethod/sqrtData Layer path: samples-cpp-registermethod/sqrt

Try out the same method via the REST Api

using the sqrt method via REST Api (in Swagger UI)using the sqrt method via REST Api (in Swagger UI)

See also the permission in the Users&Permissions settings

This permission can be added to specific users or groups. 

Custom Data Layer scope in Settings/Users&Permission/PermissionsCustom Data Layer scope in Settings/Users&Permission/Permissions

Some introduction to the code
1. Metadata in the metadata.csv
address;nodeClass;operations.read;operations.write;operations.create;operations.remove;operations.browse;description;descriptionURL;displayName;displayFormat;unit;references.readType;references.writeType;references.createType;comment
sample-cpp-registermethod/sqrt;Method;false;true;false;false;false;"gives back the square root of a float ";;;;;;types/datalayer/float32;;​

 

2. onWrite() in the main.cpp (lines 83 - 96):
// Write function of a node. Function will be called whenever a node should be written.
  virtual void onWrite(const std::string &address, const comm::datalayer::Variant *data, const comm::datalayer::IProviderNode::ResponseCallback &callback) override
  {
      //method sqrt was called. now calculating the sqrt
      comm::datalayer::Variant resultVariant;
      if(data->getType() != comm::datalayer::VariantType::FLOAT32){
        callback(comm::datalayer::DlResult::DL_TYPE_MISMATCH, nullptr);
      }
      if(double(*data) <= 0){
        callback(comm::datalayer::DlResult::DL_TYPE_MISMATCH, nullptr);
      }
      double sqrtResult = sqrt(double(*data));
      resultVariant.setValue(sqrtResult);
      callback(comm::datalayer::DlResult::DL_OK, &resultVariant);
  }

 

3.  creating of ctrlX Data Layer scope with client in main.cpp (lines 147 - 161)
comm::datalayer::Variant scopeVariant;
flatbuffers::FlatBufferBuilder builder;
auto str = builder.CreateString("sample-cpp-registermethod/**");
std::vector<flatbuffers::Offset<flatbuffers::String>> permissionR = {str};
auto scope = comm::datalayer::CreateScopeDirect(builder, 
                                            "datalayer.sqrt",
                                            "Use sqrt method", 
                                            "Allows you to use the sqrt method provided by register.datalayer.method",
                                            nullptr,
                                            nullptr,
                                            nullptr,
                                            &permissionR);
builder.Finish(scope);
scopeVariant.shareFlatbuffers(builder);
result = client->createSync("datalayer/security/scopes", &scopeVariant);
Must Read
Icon--AD-black-48x48Icon--address-consumer-data-black-48x48Icon--appointment-black-48x48Icon--back-left-black-48x48Icon--calendar-black-48x48Icon--center-alignedIcon--Checkbox-checkIcon--clock-black-48x48Icon--close-black-48x48Icon--compare-black-48x48Icon--confirmation-black-48x48Icon--dealer-details-black-48x48Icon--delete-black-48x48Icon--delivery-black-48x48Icon--down-black-48x48Icon--download-black-48x48Ic-OverlayAlertIcon--externallink-black-48x48Icon-Filledforward-right_adjustedIcon--grid-view-black-48x48IC_gd_Check-Circle170821_Icons_Community170823_Bosch_Icons170823_Bosch_Icons170821_Icons_CommunityIC-logout170821_Icons_Community170825_Bosch_Icons170821_Icons_CommunityIC-shopping-cart2170821_Icons_CommunityIC-upIC_UserIcon--imageIcon--info-i-black-48x48Icon--left-alignedIcon--Less-minimize-black-48x48Icon-FilledIcon--List-Check-grennIcon--List-Check-blackIcon--List-Cross-blackIcon--list-view-mobile-black-48x48Icon--list-view-black-48x48Icon--More-Maximize-black-48x48Icon--my-product-black-48x48Icon--newsletter-black-48x48Icon--payment-black-48x48Icon--print-black-48x48Icon--promotion-black-48x48Icon--registration-black-48x48Icon--Reset-black-48x48Icon--right-alignedshare-circle1Icon--share-black-48x48Icon--shopping-bag-black-48x48Icon-shopping-cartIcon--start-play-black-48x48Icon--store-locator-black-48x48Ic-OverlayAlertIcon--summary-black-48x48tumblrIcon-FilledvineIc-OverlayAlertwhishlist