diff --git a/doc/app_builder_env_changes.md b/doc/app_builder_env_changes.md index b3a15a5a..eb0287b6 100644 --- a/doc/app_builder_env_changes.md +++ b/doc/app_builder_env_changes.md @@ -4,9 +4,9 @@ !!! important - The newest App Builder Environment is always provided with ctrlX WORKS. + The newest App Build Environment is always provided with ctrlX WORKS. -Only the AMD64 version is supported because for every programing language supported by the ctrlX AUTOMATION SDK cross build capability is provided. +Only the AMD64 version is supported because for every programming language supported by the ctrlX AUTOMATION SDK cross build capability is provided. ### Common diff --git a/doc/appdevguide.md b/doc/appdevguide.md index 69c9d9d3..e483d1f2 100644 --- a/doc/appdevguide.md +++ b/doc/appdevguide.md @@ -103,7 +103,7 @@ To simplify the delivery of artifacts, we provide a base folder structure with d **Handover of artifacts** -Once all the required information is available in your local folder, zip the folder using Windows-zip and upload it as "**artifacts.zip**" to the ctrlX World Partner Portal space in the "**.../{company-name}/{app-name}/{version}/**" path. +Once all the required information is available in your local folder, zip the folder using Windows-zip and upload it as "**artifacts.zip**" to the ctrlX World Portal space in the "**.../{company-name}/{app-name}/{version}/**" path. !!! important To avoid problems when uploading the artifacts.zip file, please use the Windows-zip feature @@ -113,7 +113,7 @@ Once all the required information is available in your local folder, zip the fol ### 2.4 Validation and Signing Validation is typically carried out in several iterations, depending on the result of a particular validation activity. -If all the required information is provided in the ctrlX World Portal, an email to `ctrlx.world@boschrexroth.de` will trigger a validation loop. +If all the required information is provided in the ctrlX World Portal, an email to `ctrlx.world@boschrexroth.com` will trigger a validation loop. Basically, the workflow will be as follows: 1. Partner/app developer: Uploads required artifacts and informs Bosch Rexroth @@ -244,7 +244,7 @@ The basic app information is checked as a prerequisite by Bosch Rexroth, before #### 4.1.1 Artifacts Folder Template -The ctrlX World Partner Portal provides a file (artifacts.zip), which can be downloaded and extracted locally. +The ctrlX World Portal provides a file (artifacts.zip), which can be downloaded and extracted locally. This will create the required folder structure for the mandatory artifacts out-of-the-box, with default descriptions and schema files. !!!! important @@ -336,7 +336,7 @@ The following properties must be defined within the **"snapcraft.yaml"** file (s - **Title** - The general name of the app that will be shown on all sales channels and customer touch points, e.g. app overview or ctrlX App Store. This is defined together with the partner manager, as part of the business model definitions. Example: "My App" -- **Name** - The technical name of the snap. The name has to be unique in the snap universe and across all snap developer and device vendors. The snap name has to **start with "ctrlx-"** and must be **lowercase** and a **maximum length of 32 characters**. ctrlX World Partners add their company name to the snap name. Example: "ctrlx-partnername-myapp" +- **Name** - The technical name of the snap. The name has to be unique in the snap universe and across all snap developer and device vendors. The snap name has to **start with "ctrlx-"** and must be **lowercase** and a **maximum length of 32 characters**. ctrlX World partners add their company name to the snap name. Example: "ctrlx-partnername-myapp" - **Confinement** - Must be set to **"strict"** for releases. See also https://snapcraft.io/docs/snap-confinement @@ -614,7 +614,7 @@ Please contact your partner manager if a real-time extension might be required f ## 12 Licensing (**OPTIONAL**) -If you are ctrlX World Partner you must use the licensing service that is operated by Bosch Rexroth. For information how to adapt an app to the licensing service please have look on the [Licensing Page](licensing.md) +If you are ctrlX World partner you must use the licensing service that is operated by Bosch Rexroth. For information how to adapt an app to the licensing service please have look on the [Licensing Page](licensing.md) ### Appendix [Guide appendix](appdevguide_other-technologies.md) diff --git a/doc/changelog.md b/doc/changelog.md index a60f781e..582023b7 100644 --- a/doc/changelog.md +++ b/doc/changelog.md @@ -1,5 +1,10 @@ ## Software Development Kit for ctrlX AUTOMATION +### Version 1.20.0 April 02, 2023 + +* Add new samples in angular and go +* Update documentation + ### Version 1.18.0 November 30, 2022 * Adapt bulk operation from ctrlX Data Layer diff --git a/doc/connecting_qemu_vm_ctrlx.md b/doc/connecting_qemu_vm_ctrlx.md index 55b4a388..f348bd2f 100644 --- a/doc/connecting_qemu_vm_ctrlx.md +++ b/doc/connecting_qemu_vm_ctrlx.md @@ -1,4 +1,4 @@ -This document describes how SDK QEMU VMs and a ctrlX CORE can be connected. +This document describes how SDK App Build Environments (resp. QEMU VMs) and a ctrlX CORE can be connected. In our examples we are assuming a Windows 10 host with px.exe as local proxy. diff --git a/doc/images/winscp-files.png b/doc/images/winscp-files.png new file mode 100644 index 00000000..72fdc7cd Binary files /dev/null and b/doc/images/winscp-files.png differ diff --git a/doc/images/winscp-sites.png b/doc/images/winscp-sites.png new file mode 100644 index 00000000..cd9c6e2b Binary files /dev/null and b/doc/images/winscp-sites.png differ diff --git a/doc/install-scripts.md b/doc/install-scripts.md index 57f8ba46..895fd29b 100644 --- a/doc/install-scripts.md +++ b/doc/install-scripts.md @@ -1,53 +1,26 @@ -An App Build Environment instance created by ctrlX WORKS or based on the scripts under the SDK folder public/scripts/environment has a set of important install scripts in the directory __/home/boschrexroth/.__ +The directory __/home/boschrexroth/scripts/__ of an App Build Environment contains a set of important scripts. -## install-sdk.sh +In the file `/home/boschrexroth/scripts/README.md` all files are listed and described. -!!! important - Starting this script must be the first step using a new App Build Environment. - -This script downloads the ctrlX AUTOMATION SDK archive from github, extracts the content into the actual directory, sets some x permission flags and installs the ctrlx-datalayer debian package. - -Also snapcraft is installed because in the initialization phase during the first boot this snap cannot be installed. +__Hint:__ The ctrlX AUTOMATION SDK contains these scripts also in the folder scripts/environment/scripts. -Here the archive is directly installed into the home directory: +## Some important scripts - cd - ./install-sdk.sh - cd ctrlx-automation-sdk - -## install-deb.sh +### install-sdk.sh !!! important - Calling this script once is mandatory for architectural cross-builds of C++ apps. - - cd - ./install-deb.sh + Run this script first. -Important libraries for the Data Layer communication are installed for both amd64 and arm64 (aarch64) architecture. - -## install-go.sh - -If you want to develop apps in golang call this script: - - cd - ./install-go.sh - -## install-dotnet.sh - -If you want to develop apps in C# call this script: - - cd - ./install-dotnet.sh +In addition to the ctrlX AUTOMATION SDK, the ctrlx-datalayer debian package, snapcraft and libraries for cross build are installed. -## install-nodejs-npm.sh + ~/scripts/install-sdk.sh -If you want to develop apps in Node.js call this script: +Now the directory ctrlx-automation-sdk/ contains the files of the ctrlX AUTOMATION SDK. - cd - ./install-nodejs-npm.sh +### install-go, -dotnet, -nodejs -The Node.js snap inclusively the Node Package Manager npm ist installed. +These scripts are installing programming language dependend packages to be able to build apps in the according language. -## install-snapcraft.sh +### install-ctrlx-os-dev-tools.sh -This script installs snapcraft, it is called implicitly by the other scripts. \ No newline at end of file +This script installs packages needed to build a ctrlX CORE image. \ No newline at end of file diff --git a/doc/install-sources-from-github.md b/doc/install-sources-from-github.md new file mode 100644 index 00000000..7bc69fe6 --- /dev/null +++ b/doc/install-sources-from-github.md @@ -0,0 +1,52 @@ +## Introduction + +If you want to contribute the ctrlX AUTOMATION SDK you have to clone the github repository https://github.com/boschrexroth/ctrlx-automation-sdk.git. + +After this step you have to merge the runtime content of ths ctrlX AUTOMATION SDKs zip archive into this repo. + +These jobs can be initiated by __install-sdk-from-github.sh__ located in the ctrlX AUTOMATION SDK folder __scripts/__ + +## Installing a Runnable Repository + +* Open the github site [https://github.com/boschrexroth/ctrlx-automation-sdk/tree/main/scripts](https://github.com/boschrexroth/ctrlx-automation-sdk/tree/main/scripts) +* Download the script install-sdk-from-github.sh +* Install the script e.g. in the home directory of your App Build Environment +* Create a working directory e.g. ~/github +* Change into this directory and call the script + + ~/install-sdk-from-github.sh + +When the script is finished the ctrlX AUTOMATION SDK is installed into the directory ctrlx-automation-sdk and sample projects can be build at once. + +## Build Sample Project + +To build a sample project do following steps: + +Change directory e.g.: + + cd ctrlx-automation-sdk/public/samples-cpp/datalayer.provider.all-data + + +Build snap: + + build-snap-amd64.sh + + +## Troubleshooting + +github grants only a a limited number of accesses to its repositories. If you are behind a proxy this number can be exceeded very fast. In this case the download of the zip archive fails. + +To avoid this you need a github account and a personal access token - see [Creating a personal access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) + +Open the script install-sdk-from-github.sh search the line beginning with LATEST=$(curl -s and add this information: + +From + + LATEST=$(curl -s ... + +change to e.g. + + LATEST=$(curl -s -u usrxyz:tokenxyz ... + + + diff --git a/doc/licensing.md b/doc/licensing.md index 2f7e5e0a..7c08bb18 100644 --- a/doc/licensing.md +++ b/doc/licensing.md @@ -30,20 +30,20 @@ Please refer to the App Development Guide for further information. -# 2 Introduction +# 1 Introduction -From a user's perspective, device licenses are managed by the Bosch Rexroth Licensing Center [https://licensing.boschrexroth.com](https://licensing.boschrexroth.com). +Licenses are issued by the Bosch Rexroth Licensing Center [https://licensing.boschrexroth.com](https://licensing.boschrexroth.com). -Using the portal it is possible to assign licenses to a device and to download a capability response, which contains all assigned licenses for a specific device. The downloaded capability response can than be deployed to the corresponding device. +There a user can assign licenses to devices and can download a capability response, which contains all assigned licenses for a specific device. The downloaded capability response can than be deployed on the corresponding device. -The ctrlX CORE User Interfaces therefore provides a page which allows to upload a capability response and to check the currently available licenses on the device. For developers, the ctrlX CORE offers a restful API via an internal unix domain socket which can be used by an app to request and release a specific license. +The ctrlX CORE User Interfaces comes with a screen to upload the provided capability response and the possibility to check the currently available licenses on the device. The license manager feature on the ctrlX CORE offers a restful API via an internal unix domain socket, that can be used by Apps to request and release a specific license. -# 3 License Enforcement +# 2 License Enforcement -To integrate an app into the license management, please follow the instructions below. +In order to integrate license enforcement into your App, please follow the instructions below. -## 3.1 Add Content Plug to snapcraft.yaml () -To get access to the unix domain socket that provides the restful API, add the following content plug definition to the snapcraft.yaml: +## 2.1 Add Content Plug to snapcraft.yaml () +To get access to the unix domain socket that provides the restful API, add the following content plug to the snapcraft.yaml: ```yaml plugs: @@ -53,15 +53,14 @@ plugs: target: $SNAP_DATA/licensing-service ``` -This will create a folder "license-service" during installation of the app on the ctrlX CORE and provide access to the unix domain socket "licensing-service.sock" which will be located in the folder. +This will create a folder "license-service" during installation of the App on the ctrlX CORE and provide access to the unix domain socket "licensing-service.sock". -## 3.2 Adapt package-manifest.json () +## 2.2 Adapt package-manifest.json () -The app shall provide information in the package-manifest about each license that is supported. Description and title shall be human readable. -The "required" flag indicates whether a license is mandatory to use the application. Set the flag to true when the license is required and to false, when the license is optional. +The App shall provide a human readable text and a description with it´s package-manifest.json for each license that the App supports. +The "required" flag indicates, if the license is necessary for operation. Optional licenses (flag is false) extends the functionality of an application. - -```json +``` json "licenses": [ { "name": "SWL-XCx-FRW-BASIC_FOOBAR-NNNN", @@ -76,27 +75,36 @@ The "required" flag indicates whether a license is mandatory to use the applicat "required": false } ], -``` -## 3.3 Use REST API to enforce licenses + ``` + + + +## 2.3 Use REST API to Enforce Licenses -### 3.3.1 License Integration -How an app reacts when no license is present or the license is removed during runtime, can be freely chosen by the app. Nevertheless, to provide a unique user experience across multiple apps, the following best practices are recommended. +### 2.3.1 License Integration -The app should acquire the license when started or (each time) when a function is called which requires a license. Additionally, the app should check whether the license is still present on the device in regular intervals or if the license has been removed or expired. Therefore, either release and re-acquire the license or use the getCapabilities() function. This applies for both, mandatory and optional, types of licenses. +A license model must be defined for each ctrlX CORE App, so that users have the same experience across all Apps when it comes to licensing. The App shall enforce licensing, according to the App's business model as part of the contract addendum. -In case a license is not required anymore - e.g. when the app is stopped or uninstalled - the license should be released so that it is returned to the license pool and can be acquired by another app. Otherwise, the license will become available again only after a reboot of the device. +Each software license (SWL) bought by a customer generates one or more capabilities for an App on a ctrlX CORE. +Every App has to aquire a license capability from the ctrlX CORE license pool when it starts, and while it is running to check if the license is activated or removed. +One or more licenses may be defined for a particular App. In case of multiple licenses, each license has to be aquired separately (unique license ID for each license) from the ctrlX License Manager. -In case a license is missing, a warning or an error shall be displayed and/or logged and the user should be informed which licences are required to execute the specific functionality of the app. +If the license is not needed anymore, it should be returned to the license pool. This is also necessary if an App is stopped or uninstalled. +If an application crashes and the license was not returned properly, a reboot of the device is required. The reboot resets the license pool and all licenses can be aquired again. + +It is recommended to return the license back to the pool to re-aquire it again from time to time. So the App can detect if an license was removed or has expired. With this method, the App can detect license expiration very easily, and it does not need to handle expiration time by itself. + +If a license is missing, an according warning or error must be shown, and the user should be informed, which licences are defined for the App. !!! important On the ctrlX CORE, when enforcing licenses the use of the license management is mandatory. Individual implementations are not permitted. -### 3.3.2 License Manager API +### 2.3.2 License Manager API The licensing API is available on GitHub: [https://boschrexroth.github.io/rest-api-description](https://boschrexroth.github.io/rest-api-description) @@ -116,34 +124,39 @@ Implementing this API, an app is able to -### 3.3.3 Acquiring & releasing a license +### 2.3.3 License ID -Acquiring a license generates a unique license ID for that particular license. +The API call to aquire a license generates a unique license ID for that particular license +name. This unique ID can be stored in temp file. > ![](images/licensing2.png) -This ID is required to release the license. Therefore, this ID should be stored in a directory which is not affected when your application goes into a faulty state and needs to be restarted. The usage of /tmp is recommended for this. +Hint: Know more about mounting temporary disk in memory system type:tmpfs from snap documentation. -!!! hint - Know more about mounting temporary disk in memory system type:tmpfs from snap documentation. +### 2.3.4 Capability Response -### 3.3.4 Available licenses on the device (activated capabilities) -Upon request, an app may retrieve the list of available licenses on the device including all details (e.g. expiration, counter, ...). This may be used to check whether a specific license is available (and not in use) before trying to acquire it. -Nevertheless, this is optional - it is sufficient to just try to acquire a license and then check whether the acquisition request was successful. +The capability response contains list of activated license capabilities for the particular ctrlX CORE device. The App shall verify / check the licenses, which are assigned to the App, with the licenses from capabilities from response. -Sample response: +Sample capability response: > ![](images/licensing1.png) -### 3.3.5 Update license status -The API allows to upload a capability response from the license portal to update the license status on the device (e.g. add new licenses). This functionality is not required by an app itself. -# 4 Licensing Modes +# 3 Licensing Modes + +## 3.1 Overview + +On a **ctrlX CORE** controller, an App specific license is provided in the ctrlX CORE License Manager, if an according license capability response file was uploaded to the ctrlX CORE. +The capability response file contains the App specific key, for example , and the License Manager returns information for this license key. + +On a **ctrlX COREvirtual**, currently no licenses for productive use are available . +To allow a user to run and evaluate an App that enforces licensing on the ctrlX COREvirtual, the runtime on the ctrlX COREvirtual is limited to four hours + +The following table lists the three different license mode on a ctrlX CORE and the ctrlX COREvirtual, together with additional information which is provided by the License Manager for the specific license type. + -## 4.1 Overview -The license management on the **ctrlX CORE** supports several different licensing modes. THe following table gives an overview about the license modes. | License Mode | Target | Key | Usage | Additional information | |---|---|---|---|---| @@ -152,11 +165,10 @@ The license management on the **ctrlX CORE** supports several different licensin | 10 Day Trial License |ctrlX CORE |`SWL_XCR_{YOUR_APP_LICENSE_CODE}` | optional |`isPermanent` flag is `false` |Four Hour Engineering Demo License |ctrlX COREvirtual|`SWL_XCR_ENGINEERING_4H`|optional|(none specific) -As displayed in the table, there is only the "four hour engineering demo license" available on the **ctrlX COREvirtual**, which allows to evaluate a new app for a limited time (the trlX COREvirtual is terminated after four hours to prevent productive use) -The different license modes, and the expected behaviour of the App for these modes, are briefly described below. +These different license modes, and the expected behaviour of the App for these modes, are briefly described below. -## 4.2 ctrlX CORE Main License +## 3.2 ctrlX CORE Main License **Purpose:** Standard License @@ -172,7 +184,7 @@ The different license modes, and the expected behaviour of the App for these mod - When no standard app specific license is available on the device, an app shall only run if one of the other licenses is active. -## 4.3 ctrlX CORE Temporary Usage Rights (Emergency Mode) +## 3.3 ctrlX CORE Temporary Usage Rights (Emergency Mode) **Purpose:** Avoid machine downtime @@ -187,38 +199,38 @@ The different license modes, and the expected behaviour of the App for these mod **Expected App Behaviour:** - Support of this license is **mandatory**. - - The app is able to detect whether the system runs in this mode by evaluating the `tampered` flag in the response to the acquisition request (the flag is set to `true`) - - When this mode is active, the app should work as if a standard license is available. + - The App is informed with the `tampered` flag which is set to `true` in the response when acquiring such a license from the License Manager. + -## 4.4 ctrX CORE 10 Day Trial License +## 3.4 ctrX CORE 10 Day Trial License **Purpose:** Test Mode on ctrlX CORE Hardware **Description:** -- The 10 day trial license allows to use all apps - which support this license mode - for a restricted time for testing purposes. -- The license is intended for test and evaluation only and not for use in a production environment -- The license will automatically expire after 10 days. -- Other than the temporary usage rights mode, 10 day trial licenses may be used (consecutively) in case an according contractual agreement is available for all involved parties (Bosch Rexroth, Customer, ctrlX World Partner). +- Users can aquire a 10 day test license for ctrlX CORE, which allows the usage of all ctrlX CORE Apps for this time. +- It is intended for test and evaluation only, and not for use in a production environment +- This license will automatically expire after 10 days. +- Differently from the Temporary Usage Rights (which is av ailable to avoid machine downtime in case of broken devices), several 10 Day Trial Licenses can be used one after another on a device, if an according contractual agreement is available for all involved parties (Bosch Rexroth, Customer, ctrlX World Partner). **Expected App Behaviour:** - Support of this mode is **optional**. -- The app is able to detect whether the system runs in this mode by evaluating the `isPermanent` flag in the response to the acquisition request (the flag is set to `false`) - - When this mode is active, the app should work as if a standard license is available. +- The App is informed with the `isPermanent` flag set to `false` in the response when acquiring such a license from the License Manager. + +## 3.5 Four Hour Engineering Demo License on ctrlX COREvirtual -## 4.5 Four Hour Engineering Demo License on ctrlX COREvirtual +**Purpose**: Demonstration Mode on a virtual control (no ctrlX CORE hardware) -**Purpose**: Evaluation mode on a ctrlX COREvirtual **Description**: - An according special license key (`SWL_XCR_ENGINEERING_4H`) indicates that currently the limited evaluation mode is active - After 4 hours the virtual device shuts down itself to prevent a productive use. **Expected App Behaviour:** - Support of this mode is **optional**. -- In order to support this non-productive mode, apps must check for the license `SWL_XCR_ENGINEERING_4H`, which guarantees that the runtime is limited to 4 hours. +- In order to support this non-productive mode, Apps must check for the license `SWL_XCR_ENGINEERING_4H`, which guarantees that the runtime is limited to 4 hours. -## 4.6 Additional License Mode: ctrX CORE 3 Month Test License -**Purpose:** Time limited test and evaluation of apps which are in beta/prototype phase (B-Sample phase) +## 3.6 Additional License Mode: ctrX CORE 3 Month Test License +**Purpose:** Time limited test and evaluation of Apps which are in beta/prototype phase (B-Sample phase) **Description:** - This mode is not intended / available for partner apps by default. @@ -226,4 +238,4 @@ The different license modes, and the expected behaviour of the App for these mod **Copyright** -Copyright (c) 2022 Bosch Rexroth AG \ No newline at end of file +Copyright (c) 2022-2023 Bosch Rexroth AG \ No newline at end of file diff --git a/doc/numopenfilehandles.md b/doc/numopenfilehandles.md index 2273e79e..cf955d38 100644 --- a/doc/numopenfilehandles.md +++ b/doc/numopenfilehandles.md @@ -1,6 +1,6 @@ # How to Configure the maximal Number of Open File Handles -## Indroduction +## Introduction The maximum number of open file/socket handles is by default limited to 1024. This is not enough for some apps (e.g. connectivity apps or databases). diff --git a/doc/persistdata.md b/doc/persistdata.md index bff49da9..7be29483 100644 --- a/doc/persistdata.md +++ b/doc/persistdata.md @@ -1,10 +1,11 @@ **Copyright** -© Bosch Rexroth AG 2021 +© Bosch Rexroth AG 2023 This document, as well as the data, specifications and other information set forth in it, are the exclusive property of Bosch Rexroth AG. It may not be reproduced or given to third parties without our consent. **Liability** The information in this document is intended for product description purposes only and shall not be deemed to be a guaranteed characteristic, unless expressly stipulated by contract. All rights are reserved with respect to the content of this documentation and the availability of the product. ### **Table of content** + [1 Introduction](#introduction) [2 Get access to the Solutions storage](#access) @@ -19,12 +20,11 @@ This document, as well as the data, specifications and other information set for ## 1 Introduction -This How-To shows how to integrate an App into the common ctrlX persistence and storage mechanisms. -Persistence handling is done by the Solutions App (app.solutions), which is an essential part of any ctrlX CORE device. It provides a central storage for other apps that need to persist their app data. App data is saved to the storage or loaded from the storage on demand (via app editors, the "Manage app data" UI, or the Solutions REST API). +This document shows how to integrate an app into the common ctrlX persistence and storage mechanisms. +Persistence handling is done by the Solutions app (app.solutions), which is an essential part of any ctrlX CORE device. It provides a central storage for other apps that need to persist their app data. App data is saved to the storage or loaded from the storage on demand (via app editors, the "Manage app data" UI, or the Solutions REST API). ![image](images/How-To-Persist-app-data-Fig01_Overview.png) - The diagram shows that the storage provided by the Solutions app is structured into two conceptual locations: - The appdata location contains the files representing the current state of the apps and is owned by the apps. @@ -33,23 +33,23 @@ The diagram shows that the storage provided by the Solutions app is structured i The responsibilities of the Solutions app and Apps that persist their data in the Solutions storage are allocated as follows: **Solutions (app.solutions):** + - Provide file storage and make appdata directory available via the activeConfiguration symlink - Trigger and coordinate "save" and "load" operations and collect results - Manage the archived configurations (Web UI, REST API) **Apps:** + - Participate in loading and saving - Use and update the files in their appdata directories - Must not change the contents of archived configurations - - ## 2 Get access to the Solutions storage - The Solutions app exports the base directory of the storage location as a slot using a content interface. Your app must provide a plug that connects to the slot so that the $SNAP_COMMON/solutions directory becomes visible in your file system: **snapcraft.yaml:** + ```yaml plugs: active-solution: @@ -57,9 +57,8 @@ plugs: content: solutions target: $SNAP_COMMON/solutions ``` -The `$SNAP_COMMON/solution` directory contains an `activeConfiguration` symlink. Use this symlink to get the path to the appdata directory which contains the currently active app data: `$SNAP_COMMON/solutions/activeConfiguration` → `$SNAP_COMMON/solutions/DefaultSolution/configurations/appdata/` - +The `$SNAP_COMMON/solution` directory contains an `activeConfiguration` symlink. Use this symlink to get the path to the appdata directory which contains the currently active app data: `$SNAP_COMMON/solutions/activeConfiguration` → `$SNAP_COMMON/solutions/DefaultSolution/configurations/appdata/` >**Note:** > @@ -79,14 +78,13 @@ The `$SNAP_COMMON/solution` directory contains an `activeConfiguration` symlink. >- Check existence of the folder `$SNAP_COMMON/solutions/activeConfiguration` in your application logic > >In a development environment, you can check the connection of the **active-solution interface** by +> >- calling *snap connections* and checking whether there is an entry with > **interface content[solutions]** for the **plug \:active-solution** and **slot rexroth-solutions:active-solution** >- running a shell in the context of your app and checking the content of the folder `$SNAP_COMMON/solutions` which must contain a folder **DefaultSolution** and the two symlinks **activeSolution** and **activeConfiguration**. The shell can be started with *snap run --shell \.\* - - ## 3 Specify your app directories -Within the appdata root directory, define a sub-directory with a unique name as your base directory. We recommend to use your app's name in lowercase letters to avoid conflicts with other apps and allow users to easily identify your data in the file system. The screenshot shows an example with the base directories of the Motion and PLC apps, among others. +Within the appdata root directory, define a subdirectory with a unique name as your base directory. We recommend to use your app's name in lowercase letters to avoid conflicts with other apps and allow users to easily identify your data in the file system. The screenshot shows an example with the base directories of the Motion and PLC apps, among others. ![image](images/How-To-Persist-app-data-Fig02_configuation-screenshot.png) @@ -108,10 +106,25 @@ You should also explicitly declare ownership of your app directories in your pac ``` - **name** (required): The name or path of the app directory + - **description**: The title to display in the "Manage app data" content view (should be consistent with title used e.g. in sidebar menu); if omitted or empty, the app directory does not appear in the content view + - **icon**: The app icon to display in the "Manage app data" content view (should be consistent with icon used e.g. in sidebar menu); if omitted or empty, no icon is displayed in the content view -- **copyOnLoad**: Set “true” to instruct the Solutions app to copy the data from your app directory in the archive to the active configuration on load; omit (or set "false") to enable custom "smart loading"; see section "From copying to smart loading" for details -- **writeProtected**: By default, app directories and their contents can be changed by users with "Manage configurations" permissions (e.g., via WebDAV). Set "true" for your root app directory to protect your app directory and its sub-directories in the active configuration against changes by users; omit (or set "false") for specific sub-directories to provide write-access to those directories. Since XCR-V-0112. + +- **copyOnLoad** (default: *false*): Set *true* to instruct the Solutions app to copy the data from your app directory +in the archive to the active configuration on load; omit (or set *false*) to enable custom "smart loading"; see section +"From copying to smart loading" for details + + > Since XCR-V-0120, app directories with active copyOnLoad are only copied if the corresponding app is installed + > and enabled on loading. + +- **writeProtected** (default: *true*): App directories and their contents in the active configuration are protected +against changes through the WebDAV interface and the Solutions UI by default. Set *false* to allow changes for a +directory and its subdirectories, which requires that your app can detect and handle potential changes appropriately. +Since XCR-V-0112. + + > Since XCR-V-0120, the default value of the writeProtected attribute is *true* in order to protect app directories + > against unintended changes. Configuration contents should generally have the following properties: @@ -121,14 +134,15 @@ Configuration contents should generally have the following properties: We recommend JSON as the file format where possible, as it supports these properties. You may also consider to provide corresponding JSON-schema files to enable guidance and validation. In any case, JSON files should contain a root object (NOT an array) to enable schema references and extendibility. -**Remark:** -Your app can specify "private files" inside your appdata directories in order to exclude them from save and load operations. See appendix "App-private files" for details. +> **Note:** +> An app may specify "private files" inside its appdata directories in order to exclude them from save and load operations. See appendix "App-private files" for details. ## 4 Register for saving and loading In order to participate in the save and load operations triggered by the Solutions app, your app must register its own save and load commands. The following example shows how to register a save and a load command for Motion settings by adding the respective command declarations to the package manifest: **package-manifest.json:** + ```json "commands": { "activeConfiguration": { @@ -149,24 +163,26 @@ In order to participate in the save and load operations triggered by the Solutio } } ``` + For each command, the following elements must be specified: - **id** (required): a string serving as the identifier of the save or load command; must be unique within the “commands/activeConfiguration/save” and “commands/activeConfiguration/load” paths, respectively - **subject** (required): a string denoting what will be saved or loaded; used to inform users, e.g. in messages like “Loading *motion settings*” or “Failed to load *motion settings*” -- **url** (required): a string representing the request URL; URLs starting with a slash are interpreted to be relative to https://\ (the control itself). Declare an absolute URL if you need to specify a port, e.g. `http://localhost:5555/my-app/api/v1/save`. The URL is used for HTTP POST requests which include command parameters in the request body (see section "Request parameters" for details) +- **url** (required): a string representing the request URL; URLs starting with a slash are interpreted to be relative to > (the control itself). Declare an absolute URL if you need to specify a port, e.g. `http://localhost:5555/my-app/api/v1/save`. The URL is used for HTTP POST requests which include command parameters in the request body (see section "Request parameters" for details) By default there is no defined order of command execution. Starting with version XCR-V-0112, a command may declare that it needs to be executed **after** other commands. If this is required (which should be the exception), add an after element to your command declaration with an array containing the IDs of the predecessor commands. ->**Note: Hint for developers providing Data Layer endpoints for loading and saving** +>**Hint for developers providing Data Layer endpoints for loading and saving** > >In order to make the Data Layer endpoints for saving and loading a configuration consistent, the respective URLs should adhere to the following pattern: > >\/\<**technology**\>/admin/cfg/\ > >Examples: -> - /automation/api/v1/**scheduler**/admin/cfg/save(or load) -> - /automation/api/v1/**fieldbuses/ethercat/master**/admin/cfg/save (or load) -> - /automation/api/v1/**motion**/admin/cfg/save (or load) +> +> - /automation/api/v1/**scheduler**/admin/cfg/save(or load) +> - /automation/api/v1/**fieldbuses/ethercat/master**/admin/cfg/save (or load) +> - /automation/api/v1/**motion**/admin/cfg/save (or load) ## 5 Implement saving and loading @@ -194,6 +210,12 @@ Any errors or problems that occur during phases 2-5 are collected and reported t A more detailed description of the load phases and example sequences can be found in the Appendix. +> **Note:** Starting with XCR-V-0120, a save operation is triggered when a load operation is completed. This ensures that +> the content of the active configuration (appdata directory) is consistent with the data that is active in the apps. +> +> The save requests of this special save operation have the same id as the preceding load requests. Participants may +> ignore those save requests if they update their app data on loading. + ### Request parameters The following information is sent as request parameters to all participants in all save and load phases: @@ -203,6 +225,7 @@ The following information is sent as request parameters to all participants in a - **phase**: specifies the current processing phase of a save or load operation; one of the phases described in section "Processing sequences"; e.g., "load" The request parameters are provided in the request body as a JSON object with the following structure (using the sample values from above): + ```json { "configurationPath": "solutions/DefaultSolution/configurations/", @@ -211,6 +234,7 @@ The request parameters are provided in the request body as a JSON object with th } ``` + ### Expected behavior Participants must consider the following conditions and constraints in their command implementations. @@ -234,9 +258,9 @@ The dynamicDescription field can provide specific information for the user, like The field may contain “\n“ to separate cause and hint in the result output of the UI, e.g. “Format error in X.json.\nAdapt file or use motion editor to fix/recreate axis. [282xy5]” > **Common response if apps require Setup state for loading (since XCR-V-0116)** -> +> > If participants require Setup state for loading, they should in the query phase -> +> > - Respond with status code 409 (Conflict) > - Return a Problem object with the common mainDiagnosisCode **080F0E00** ("Loading configuration not possible in current state") > - Not write diagnoses to the Logbook @@ -249,14 +273,14 @@ Example of diagnostic entries as they would appear in the Logbook: | Level | Date | Unit | Code | Description | | --- | --- | --- | --- | ---| -| Info | 06/04/2020, 10:33:11.964 | web.solutions | 080A0401 | Loading configuration successfully finished [282xy5] | -| ... | ... | ... | ... |... | -| ... | ... | ... | \

\ | \

\
\ [282xy5]
\ | -| Info | 06/04/2020, 10:31:20.733 | web.automation | \
|Trace message\
Scheduler successfully prepared for loading [282xy5] | -| Info| 06/04/2020, 10:31:19.820| web.solutions| 080A0400 | Loading configuration started [282xy5]| +| Info | 06/04/2020, 10:33:11.964 | web.solutions | 080A0401 | Loading configuration successfully finished [282xy5] | +| ... | ... | ... | ... |... | +| ... | ... | ... | \

\ | \

\
\ [282xy5]
\ | +| Info | 06/04/2020, 10:31:20.733 | web.automation | \
|Trace message\
Scheduler successfully prepared for loading [282xy5] | +| Info| 06/04/2020, 10:31:19.820| web.solutions| 080A0400 | Loading configuration started [282xy5]| ->**Note:** ->The id of a save or load operation can also be found on and copied from the "Manage app data" page (Save or Load report) in order to search for corresponding messages in the Logbook. The diagnostic numbers may be used to find the beginning and end of the respective operation in the Logbook, e.g. "080A0400" denoting "Loading configuration started". +> **Note:** +> The id of a save or load operation can also be found on and copied from the "Manage app data" page (Save or Load report) in order to search for corresponding messages in the Logbook. The diagnostic numbers may be used to find the beginning and end of the respective operation in the Logbook, e.g. "080A0400" denoting "Loading configuration started". #### Robustness @@ -280,9 +304,9 @@ The coordinator (Solutions app) ensures the following properties: ### From copying to smart loading -Apps must update their appdata sub-directory contents during the load operation to reflect the data which has been loaded and is now active in the apps. +Apps must update their appdata subdirectory contents during the load operation to reflect the data which has been loaded and is now active in the apps. -A first basic implementation may be to just copy the directory contents from the "configuration to load" to the corresponding appdata sub-directory. The Solutions app provides a default implementation of this file copy functionality. To activate this functionality, use the copyOnLoad option in your app directory declarations (cf. section "Specify your app directories"). +A first basic implementation may be to just copy the directory contents from the "configuration to load" to the corresponding appdata subdirectory. The Solutions app provides a default implementation of this file copy functionality. To activate this functionality, use the copyOnLoad option in your app directory declarations (cf. section "Specify your app directories"). The following example shows how a set of copyOnLoad declarations would be applied for a given configuration: @@ -312,14 +336,12 @@ The following example shows how a set of copyOnLoad declarations would be applie f: false (inherited from e) g: true (inherited from a) - However, an app might improve the load functionality by evaluating the changes to be applied during load. The app may determine that state changes (e.g., stopping the PLC for loading) are actually not required depending on the kind of data to load. Some participants may even be able to skip a load operation completely if their part of the configuration has not changed. If you want to take control and be able to evaluate differences between the configuration files and the appdata files, -- declare your base directory or specific sub-directories you would like to handle yourself in the package manifest -- omit the copyOnLoad option (or set copyOnLoad to "false") - +- declare your base directory or specific subdirectories you would like to handle yourself in the package manifest +- omit the copyOnLoad option (or set copyOnLoad to *false*) >**Note:** For compatibility reasons with previous ctrlX CORE releases, copyOnLoad is executed before the "prepare" phase. If you do not use copyOnLoad, you should persist your app data in the "load" phase as specified; see the "Annotated load process" in the Appendix for details @@ -344,7 +366,6 @@ For compatibility reasons with previous ctrlX CORE releases, copyOnLoad is execu ![image](images/How-To-Persist-app-data-Fig06_Loading(FAILED).png) - ### Problem schema definition Failure responses to command requests must adhere to the following schema: @@ -471,7 +492,7 @@ Problem: Apps may need to store files in their appdata directories which are only needed at runtime. These files (or directories) have to be ignored on loading and when saving the appdata to an archived configuration. -An app can specify such files using the "appPrivateFiles" element in the configuration section of its manifest. The element value is an array of strings where each string represents a regular expression following the RE2 syntax (https://golang.org/s/re2syntax). The expressions describe paths and names of files to be considered as private and are checked case-insensitively. +An app can specify such files using the "appPrivateFiles" element in the configuration section of its manifest. The element value is an array of strings where each string represents a regular expression following the RE2 syntax (). The expressions describe paths and names of files to be considered as private and are checked case-insensitively. The following example shows the declaration of "appPrivateFiles" with 3 regular expressions and the declaration of the app's root directory: @@ -502,10 +523,39 @@ Hints for the regular expressions: The characters "\[]().\\^\$|?*+{}" have speci Examples for regular expressions (with an app root directory of "my-app") - | Regular expression| Meaning | | --- | --- | | "^my-app/private/" | defines the my-app/private directory and its content as private | -| "^my-app/mixed/[^/]+.\.bak" | defines all files with extension .bak within the my-app/mixed directory as private | -|"^my-app/mixed/$" | defines the my-app/mixed directory itself as private so that it is not removed if empty| +| "^my-app/mixed/[^/]+.\.bak" | defines all files with extension .bak within the my-app/mixed directory as private | +|"^my-app/mixed/$" | defines the my-app/mixed directory itself as private so that it is not removed if empty| + +### Accessing configuration files per WebDAV + +The configuration files are available via WebDAV protocol under the ctrlx-device web address with base path of "solutions/webdav", eg. access the configuration.json file content of appdata: + + https://localhost:8443/solutions/webdav/appdata/configuration.json + +See also: [golang WebDAV client](../samples-go/webdav.client/readme.md) and [nodejs WebDAV client](../samples-node/webdav-client/readme.md) + +### Accessing configuration files with WinSCP + +[WinSCP](https://winscp.net/) is a windows app, which allows access to a remote file system via WebDAV. + +#### Connect to a crtlX device + +Start WinSCP, login with: + + File protocol: WebDAV + Host name: IP-address or hostname of the device + Port number: 443 or 8443 for a virtual control + User name and Password: credentials on the ctrlX-device + +![](images/winscp-sites.png) + +The user needs manage configuration rights to access the files. + +Access the configuration files located in **/solutions/webdav** + +![](images/winscp-files.png) +The folder "appdata" contains the files of the active configuration. The other folders are configuration archives. diff --git a/doc/px.md b/doc/px.md index f19c5fce..1ec92429 100644 --- a/doc/px.md +++ b/doc/px.md @@ -2,7 +2,7 @@ This documentation is __for Windows hosts only without direct internet access__. -## Indroduction +## Introduction Host computers without direct internet access are using a proxy server to connect to the internet. __In this case we have to provide the proxy service also for a SDK builder VM running on this host__. @@ -19,39 +19,48 @@ For more informations about Px see [What is Px](https://github.com/genotrance/px ## Installation of Px as Local Proxy Server -* Download Px.exe from [https://github.com/genotrance/px](https://github.com/genotrance/px) - Px for Windows Latest -* Copy Px.exe to a separate folder -* Configure Px.exe +* Open [https://github.com/genotrance/px/releases/](https://github.com/genotrance/px/releases/) +* Click button Latest +* Click px-v?.?.?-windows.zip (v?.?.? e.g. v0.8.4) +* The zip archive will be downloaded +* Unzip the content e.g. to c:\tools\px +* Create a px-start.bat file in with the content: - px.exe --proxy=__address_of_your_network_proxy__:__port__ --save -!!! important - Px.exe provides both http and https access via default port __3128__. If this port is not available on the host it can be changed in px.ini BUT: The alternative port has to be changed in the VM too - see [Setup a QEMU VM](setup_qemu_ubuntu.md) and [Setup a Virtual Box VM](setup_windows_virtualbox_ubuntu.md). - - -* Add Px to the Windows registry to run on startup: + cd c:\tools\px - px.exe --install + px.exe +* Manually call this bat file Enter this command for further usage of Px: px.exe --help +For automatically run at startup do following steps: + +* Create a link to px-start.bat +* Open the startup folder with Windows logo key + R, enter __shell:startup__ +* Move the link to px-start.bat into this folder + + +!!! important + Px provides both http and https access via default port __3128__. If this port is not available on the host it can be changed in px.ini BUT: The alternative port has to be changed in the VM too - see [Setup a QEMU VM](setup_qemu_ubuntu.md) and [Setup a Virtual Box VM](setup_windows_virtualbox_ubuntu.md). + -## Proxy Settings in the SDK Builder VM + +## Proxy Settings in the App Build Environment As mentioned a VM running on a host without direct internet access has to use a proxy server too. For the VM Px on the host is reachable via the URL __http://10.0.2.2:3128__ -Note: 10.0.2.2 is the IP address of the host from the perspective of the VM. See also [QEMU Virtual Machine Networking](setup_qemu_ubuntu.md#qemu-virtual-machine-networking) +Note: 10.0.2.2 is the IP address of the host from the perspective of the App Build Environment. See also [QEMU Virtual Machine Networking](setup_qemu_ubuntu.md#qemu-virtual-machine-networking) For your information only - do not change if not necessary: This URL is stored as so called "Proxy Settings" in the VM e.g. in following files: - * /etc/environment *1) * /etc/wgetrc * ~/.nuget/NuGet/NuGet.Config @@ -66,7 +75,7 @@ This URL is stored as so called "Proxy Settings" in the VM e.g. in following fil ## Troubleshooting -Check proxy function +Check proxy function in the App Build Environment: wget http://www.boschrexroth.com @@ -76,7 +85,7 @@ If no error occurs the internet access via the proxy server is working. In this Check the following points if there are problems with Px: -* SDK Builder VM: Are the proxy settings fitting to the px.ini file on the host? +* Are the proxy settings Proxy Settings in the App Build Environment fitting to the px.ini file on the host? * For more informations about the settings in px.in see [px.ini on github](https://github.com/genotrance/px/blob/master/px.ini) * Host PC: Is another proxy running e.g. cntlm? * Host PC: Enable logging with parameter log = 1 in px.ini diff --git a/doc/quick-start-guide.md b/doc/quick-start-guide.md index 43705cf5..5de44fae 100644 --- a/doc/quick-start-guide.md +++ b/doc/quick-start-guide.md @@ -2,7 +2,7 @@ With the help of this guide you will be able to build your first snap with one o ## Prerequisites -* Install ctrlX WORKS >= 1.14 with function 'App Build Environment' on your Windows host computer +* Install ctrlX WORKS >= 1.20 with function 'App Build Environment' on your Windows host computer * If your Windows host computer is behind a proxy server, install and run [PX.exe](px.md). @@ -21,9 +21,11 @@ On password prompt enter `boschrexroth` * __Install the latest ctrlX AUTOMATION SDK from github__ -From the home directory call this script: +Call this script: - ./install-sdk.sh + ~/scripts/install-sdk.sh + +The script downloads downloads ctrlx-automation-sdk.zip from github and unzips it to the folder /home/boschrexroth/ctrlx-automation-sdk/ * __Change to project folder /home/boschrexroth/ctrlx-automation-sdk/samples-cpp/datalayer.register.node__ @@ -37,7 +39,9 @@ To build a snap for a ctrlX CORE enter: ./build-snap-arm64.sh -* __From your Windows host copy the snaps to your local file system__ +As a result a snap file `sdk-cpp-registernode_...._amd64.snap` respectively `sdk-cpp-registernode_...._arm64.snap` will be created. + +* From your __Windows host__ copy the snaps from your App Build Environment to your Windows file system__ Start cmd.exe and enter this command: diff --git a/doc/references.md b/doc/references.md index 37324867..c2435984 100644 --- a/doc/references.md +++ b/doc/references.md @@ -24,3 +24,4 @@ Api reference (doxygen generated) * [c#](https://apps.boschrexroth.com/docs/ctrlx/csharp/html/index.html) * [python](https://apps.boschrexroth.com/docs/ctrlx/python/html/index.html) + diff --git a/doc/remote-build.md b/doc/remote-build.md index 6e8a98d3..857dc702 100644 --- a/doc/remote-build.md +++ b/doc/remote-build.md @@ -1,14 +1,21 @@ +## Using Launchpad build farm + From snapcraft version 3.9+ [Canonical](https://canonical.com/) enables anyone to run a multi-architecture snap build process on remote servers using the [Launchpad build farm](https://launchpad.net/builders): snapcraft remote-build --build-on=arm64,amd64 --launchpad-accept-public-upload -You can find a detailed documentation here: [Remote build](https://snapcraft.io/docs/remote-build) -For support please consult the [Snapcraft Forum](https://forum.snapcraft.io/). !!! important Using the snapcraft remote-build feature makes your projects public. So it is primarily useful for open source software projects. +## Further Information + +You can find a detailed documentation here: [Remote build](https://snapcraft.io/docs/remote-build) + +For support please consult the [Snapcraft Forum](https://forum.snapcraft.io/). + + diff --git a/doc/samples.md b/doc/samples.md index 4673ad57..052e7e8e 100644 --- a/doc/samples.md +++ b/doc/samples.md @@ -3,19 +3,23 @@ Applications (snaps) for ctrlX CORE targets can be written in several programming language or even as shell scripts. -For creating your own applications, the ctrlX AUTOMATION SDK offers sample projects that can be used directly or as templates. The sample projects are saved in sub folders according to their programming language or their type. - -Here an overview of the sample project types and their subfolders. - -| Sample Project Type | Link to Projects | -| :------------------ | :----------------------------------------------------- | -| __C/C++__ | [samples-cpp/README.md](samples-cpp/README.md) | -| __Go__ | [samples-go/README.md](samples-go/README.md) | -| __Python__ | [samples-python/README.md](samples-python/README.md) | -| __.NET__ | [samples-net/README.md](samples-net/README.md) | -| __Node.js__ | [samples-node/README.md](samples-node/README.md) | -| __Shell scripting__ | [samples-sh/README.md](samples-sh/README.md) | -| __Snap__ | [samples-snap/README.md](samples-snap/README.md) | +For creating your own applications, the ctrlX AUTOMATION SDK offers sample projects that can be used as source of code snippets as templates. The sample projects are saved in sub folders according to their programming language or their type. + +Here an overview of the sample project types and their subfolders. + +!!! important + Run the install script listet in column three once before you are working with one or more sample projects. + These scripts are located in __/home/boschrexroth/scripts__. See also [install-scripts](install-scripts.md). + +| Sample Project Type | Link to Projects | Install Script +| :------------------ | :------------------------------------------------------ | :------------------------ | +| __C/C++__ | [samples-cpp/README.md](samples-cpp/README.md) | +| __Go__ | [samples-go/README.md](samples-go/README.md) | ~/scripts/install-go.sh +| __Python__ | [samples-python/README.md](samples-python/README.md) | +| __.NET__ | [samples-net/README.md](samples-net/README.md) | ~/scripts/install-dotnet-sdk.sh +| __Node.js__ | [samples-node/README.md](samples-node/README.md) | ~/scripts/install-nodejs-npm.sh +| __Shell scripting__ | [samples-sh/README.md](samples-sh/README.md) | +| __Snap__ | [samples-snap/README.md](samples-snap/README.md) | | __IEC 61131-3__ | [samples-iec61131/README.md](samples-iec61131/README.md)| @@ -40,7 +44,9 @@ You can call these scripts from the command line: At the end of the build process the snap file should be available in the root folder of your project. -## Installing a Snap +See below for further Run Build Task items. + +## Installing a Snap Manually Right click the snap file in the Visual Studio Code EXPLORER and select 'Download'. Visual Studio Code stores it in your home directory on your host computer. For Windows 10 this is %USERPROFILE%, in Linux this is: ~/ @@ -50,4 +56,40 @@ Start a Web browser, login into your ctrlX CORE: * Switch to Service Mode * Click Install from file * Select the downloaded file -* Switch to Operation Mode \ No newline at end of file +* Switch to Operation Mode + +## Building and Installing a Snap Automated by Script + +Using the bash script __build-upload-log-snap.sh__ in the ctrlX AUTOMATION SDK folder scripts/ +You can create a snap file, upload it, install it on a ctrlX CORE and view the log output. + +The script can be started either from the command line or with the additional Run Build Task items of the Visual Studio Code IDE. + +### Starting Script from the Command Line + +Change into a sample project folder (e.g. samples-cpp/datalayer.client) and enter + + ../../scripts/build-upload-log-snap.sh -help + +All parameters and their default values are listed. + +E.g. to build and install a snap for a ctrlX CORE virtual with Network Adapter enter + + ../../scripts/build-upload-log-snap.sh -NA + +But we recommend calling this script from Visual Studio Code. See next chapter. + +### Starting Script as Visual Studio Build Task + +Additional to the two Build Tasks mentioned above there are further tasks: + +* __Build upload snap - ctrlX CORE virtual Network Adapter__ +* __Build upload snap - ctrlX CORE virtual Port Forwarding__ +* __Build upload log snap - ctrlX CORE 192.168.1.1__ +* __Build upload snap__ + +The first three tasks are calling the script with the parameter set needed for the according destination. There is sno need to select further parameters. + +If you are choosing the last item each parameter is prompted. + +Feel free to add more tasks or adapt the existing ones. diff --git a/doc/setup_overview.md b/doc/setup_overview.md index 5d2677f9..189f07a2 100644 --- a/doc/setup_overview.md +++ b/doc/setup_overview.md @@ -4,9 +4,13 @@ To develop ctrlX CORE applications with the ctrlX AUTOMATION SDK we need a so ca * In [ctrlX WORKS App Build Environment](setup_qemu_ctrlx_works.md) the __recommended way__ creating and running an App Build Environment is described. +* [Important Installation Scripts](install-scripts.md) gives an overview of scripts needed to install programming language dependent tools. + * If ctrlX WORKS cannot be used the chapter [QEMU Virtual Machine](setup_qemu_ubuntu.md) shows how QEMU can be installed as standalone app and how a QEMU VM can be setup as App Build Environment. * [VirtualBox Virtual Machine](setup_windows_virtualbox_ubuntu.md) describes how to setup such a VM to use it as App Build Environment. * [Native Ubuntu 20.04](setup_ubuntu.md) shows how to setup a bare-metal machine to use it as App Build Environment. +* [Install Sources from github](install-sources-from-github.md) describes how to download and install the github repository __ctrlX AUTOMATION Software Development Kit__ [https://github.com/boschrexroth/ctrlx-automation-sdk](https://github.com/boschrexroth/ctrlx-automation-sdk) + diff --git a/doc/setup_qemu_ctrlx_works.md b/doc/setup_qemu_ctrlx_works.md index cc61a7e8..f2822976 100644 --- a/doc/setup_qemu_ctrlx_works.md +++ b/doc/setup_qemu_ctrlx_works.md @@ -30,7 +30,8 @@ Select App Build Environments on the side bar of ctrlX WORKS. The list of instal ### Start an App Build Environment * Start a App Build Environment with the play `>` icon. -* On first start the Ubuntu image will be downloaded and the environment will be installed. This will take some time. During this state no login will be possible. When this process is complete the VM will shutdown. Click the play icon again to restart. +* On first start the Ubuntu image will be downloaded and the environment will be installed. This will take some time. In this phase no login will be possible. When the initialization phase is finished the VM will shutdown automatically. +* Click the play icon again to restart the App Build Environment. * When the environment is up ctrlX WORKS will show 'Online' in column State. ### Working with an App Build Environment @@ -39,7 +40,7 @@ You can open a SSH connection (secure shell) by clicking the according link in t For the login a password is required, it is __boschrexroth__. -We recommend to add your public key in the hosts id_rsa.pub file to the file authorized_keys in the VMs directory /home/boschrexroth/.ssh/. So password input on each login is obsolete. +We recommend to add your public key contained in the __hosts__ id_rsa.pub file to the file authorized_keys in the VMs directory /home/boschrexroth/.ssh/. So password input on each login is obsolete. Therefor you can use the bat file ssh-keygen-copy-id.bat in the destination directory of the VM (see below). diff --git a/doc/setup_qemu_ubuntu.md b/doc/setup_qemu_ubuntu.md index 7ec91e90..f1135768 100644 --- a/doc/setup_qemu_ubuntu.md +++ b/doc/setup_qemu_ubuntu.md @@ -1,66 +1,17 @@ -!!! important - We recommend to use ctrlX WORKS setting up and operating an App Build Environment. This guide is only for use cases where ctrlX WORKS cannot be used. - -Creating and running an App Build Environment for the ctrlX AUTOMATION SDK is possible because the SDK archive contains all configuration and script files. - -This is the recommended constellation: - -* The QEMU software should be run on an __AMD64__ based host computer with hardware acceleration. QEMU supports both Windows 10 and Linux host systems. - -* For the QEMU virtual machine also __AMD64__ should be selected as CPU architecture. - -This combination provides best performance conditions. - -The installation of QEMU, further required tools and QEMU virtual machines is described in the next chapters. - - -## Preparations - -Download the archive ctrlX AUTOMATION SDK from [github boschrexroth/ctrlx-automation-sdk/releases](https://github.com/boschrexroth/ctrlx-automation-sdk/releases) to your host computer and unpack at least the folder __public/scripts/environment__. - -This folder contains all necessary files and scripts for both Windows 10 and Linux hosts. - -## Install QEMU - -### Linux Host - -Change to the SDK folder public/scripts/environment and set x file permissions: - - $ chmod a+x *.sh - -#### Install QEMU on Linux Host - -Because the newest QEMU software is not provided as Debian package we have to download the source files, compile the project and install the binaries. This is done automatically by the script __install-qemu-on-host.sh__ stored in the SDK folder __public/scripts/environment/__. +This chapter describes how to setup and run App Build Environments without using ctrlX WORKS. -To install QEMU do following steps: +Remember ctrlX WORKS provides all necessary actions required to deal with app build environments. -* Copy the script install-qemu-on-host.sh into a tempory folder on your Linux host computer. -* Change to the temporary folder and start these commands: - - $ chmod a+x install-qemu-on-host.sh - $ sudo ./install-qemu-on-host.sh - -This procedure will take some time - at the end QEMU is installed. - -#### Install KVM on Linux Host - -We recommend to install KVM (Kernel-based Virtual Machine) on your host sytem. - -Change to the SDK folder public/scripts/environment and start - - ./install-kvm-on-host.sh - -See here for further informations: - -[How to Install Kvm on Ubuntu 20.04](https://linuxize.com/post/how-to-install-kvm-on-ubuntu-20-04/) +This is the recommended constellation: -[linux-kvm](https://www.linux-kvm.org/page/Documents) +* Despite QEMU supports both Windows and Linux we are recommending to use a Windows host operating system . +* Host and guest machine should use CPU architecture amd64. Snaps for an arm64 target are build via cross build. -### Windows 10 Host +## Installation on Windows 10 Host -#### Install QEMU on Windows 10 Host +### QEMU on Windows Download and install the newest version of QEMU for Windows from [https://qemu.weilnetz.de/w64/](https://qemu.weilnetz.de/w64/). @@ -69,7 +20,7 @@ Download and install the newest version of QEMU for Windows from [https://qemu.w See [How do I set or change the PATH system variable?](https://www.java.com/en/download/help/path.html) -#### Install Windows Hypervisor Platform +### Install Windows Hypervisor Platform We recommend to install __Windows Hypervisor Platform__: @@ -99,40 +50,44 @@ __Hints:__ * If Windows Hypervisor Platform cannot be installed for any reason, we recommend using the Intel Hardware Accelerated Execution Manager (HAXM). The installation is described here [Installing HAXM](https://docs.microsoft.com/en-us/xamarin/android/get-started/installation/android-emulator/hardware-acceleration?pivots=windows#installing-haxm) -#### Install Px.exe as Local Proxy Server +### Install Px.exe as Local Proxy Server See [Use PX.exe as Local Proxy on a Windows Host](./px.md). -## Create an Instance of an AMD64 QEMU Virtual Machine +## Installation on Linux Host + +You have to install both QEMU and KVM on your host system. + +The installation process is descriped in the internet e.g. -A virtual machine should be installed and started within a separate folder on your host computer. Therefor SDK folder __public/scripts/environment__ contains these scripts: +[How to Install QEMU on Ubuntu to Set Up a Virtual Machine](https://www.makeuseof.com/how-to-install-qemu-ubuntu-set-up-virtual-machine/). -* __create-new-vm-amd64-noproxy.bat, .sh__: creates an AMD64 VM with direct internet access -* __create-new-vm-amd64-proxy.bat, .sh__: creates an AMD64 VM using a proxy server +See also: + +[How to Install Kvm on Ubuntu 20.04](https://linuxize.com/post/how-to-install-kvm-on-ubuntu-20-04/) -__These scripts are expecting the destination folder of your new VM as argument.__ +[KVM](https://www.linux-kvm.org/page/Documents) -To create e.g. a new amd64 VM instance with proxy usage on a Windows host do following steps: +## Running the QEMU Virtual Machine -* Create a separate folder on your host computer D:\qemuvm\amd64-proxy-1 -* Start cmd.exe -* Change to the SDK folder __public/scripts/environment__ -* Call create-new-vm-amd64-proxy.bat D:\qemuvm\amd64-proxy-1 +### Create an Instance of a QEMU Virtual Machine -All necessary files for this new VM are copied into the destination folder. +Do following steps: -Notice: +* Create a new folder (on a disk with enough free disk space) +* Copy the content of the SDK folder __public/scripts/environment__ into your instance folder. -The aarch64 .bat/.sh__ files are obsolete and should not be used. +__Hint:__ You can download the folder from here + +[ctrlx-automation-sdk/scripts/environment/](https://github.com/boschrexroth/ctrlx-automation-sdk/tree/main/scripts/environment) -## Running a QEMU Virtual Machine ### Start the QEMU Virtual Machine To start the QEMU VM instance change to its installation folder and run one of these script files: -* __launch-amd64-noproxy.bat, .sh__: If the VM has direct internet access -* __launch-amd64-proxy.bat, .sh__: If the VM has to use a proxy server on the host computer +* __launch-amd64-noproxy (.bat, .sh) : If the VM has direct internet access +* __launch-amd64-proxy (.bat, .sh): If the VM has to use a proxy server on the host computer The VM is started as console application, you can see the trace output. @@ -161,12 +116,6 @@ For forwarding further ports e.g. __502 (Modbus)__ just extend this line e.g.: During the first connection with Visual Studio Code enter: __ssh -p 10022 boschrexroth@127.0.0.1__ password is __boschrexroth__ -### Install the ctrlX AUTOMATION SDK and Additional Software After First Boot - -Start your VM, from your host start a SSH session and login with __boschrexroth/boschrexroth__. - -Please regard instructions in chapter [Important Install Scripts](install-scripts.md). - ### Shutdown It's very important to shutdown the __QEMU VM__ properly. So initiate a shutdown e.g. with this command on your VM console: diff --git a/doc/setup_ubuntu.md b/doc/setup_ubuntu.md index 4d0ec017..ac77df5f 100644 --- a/doc/setup_ubuntu.md +++ b/doc/setup_ubuntu.md @@ -1,6 +1,11 @@ +## Introduction You can use a bare-metal machine with an Ubuntu Desktop or Ubuntu Server operating system to develop apps with the ctrlX AUTOMATION SDK. -The installation of the required packages, the SDK itself and some of the programming language installation scripts is equal to the procedure for a VirtualBox Virtual Machine. +The installation of the required packages, the ctrlX AUTOMATION SDK and some of the programming language installation scripts is equal to the procedure for a VirtualBox Virtual Machine. You can find the informations in [VirtualBox Virtual Machine](setup_windows_virtualbox_ubuntu.md) from chapter 'Setup Standard Packages' to the end of the document. + +## Install the ctrlX AUTOMATION SDK + +See here [Install Sources from github](install-sources-from-github.md) \ No newline at end of file diff --git a/doc/setup_windows_virtualbox_ubuntu.md b/doc/setup_windows_virtualbox_ubuntu.md index 9ff3500d..1d8f4837 100644 --- a/doc/setup_windows_virtualbox_ubuntu.md +++ b/doc/setup_windows_virtualbox_ubuntu.md @@ -68,13 +68,20 @@ You might want to update your distribution and install essential packages for de ### Setup Standard Packages -Packages in QEMU based VMs created by ctrlX WORKS are installed automatically. In the configuration file [cloud-config-amd64](https://github.com/boschrexroth/ctrlx-automation-sdk/blob/main/scripts/environment/cloud-config-amd64) these packages are listed under the section __packages:__ +In QEMU based VMs created by ctrlX WORKS, required packages are installed automatically. -You can copy the list and create an install command, e.g. +Here you have to install them manually: -packages: - ssh - zip - unzip ... +1. Open the according user-data-img file e.g. with Windows notepad. In the text part of this file you will find the section packages (here the first lines only): - sudo apt-get install -y ssh zip unzip ... + packages: + - zip + - unzip + + +2. Copy the package list, remove the '-' character and create a comand line e.g. + + sudo apt-get install -y zip unzip ... !!! important Install ALL listed packages. diff --git a/doc/working-with-app-builder-envs.md b/doc/working-with-app-builder-envs.md index 7c78e2e7..4bcc0874 100644 --- a/doc/working-with-app-builder-envs.md +++ b/doc/working-with-app-builder-envs.md @@ -1,21 +1,21 @@ -This document describes how to work with App Builder Environments (QEMU based VMs). +This document describes how to work with App Build Environments (QEMU based VMs). -## Best Practice working with App Builder Environments +## Best Practice working with App Build Environments -We recommend to use App Builder Environments (QEMU VMs) as follows: +We recommend to use App Build Environments (QEMU VMs) as follows: -1. Create a new App Builder Environment with ctrlX WORKS and start it (the newest version of Ubuntu 20.04 LTS is automatically downloaded). +1. Create a new App Build Environment with ctrlX WORKS and start it (the newest version of Ubuntu 20.04 LTS is automatically downloaded). 2. After first boot login and install only necessary additional software components using the install scripts in /home/boschrexroth/e.g.: install-sdk.sh, install-deb.sh and install-go.sh 3. We recommend to work with the free and open source distributed version control system __git__: Create a repository for your project and clone it into your App Buiulder Environment. 4. Create a new branch for your working package. 5. Do your work within this branch, commit and push your changes as often as it makes sense. -6. If your work is done and all changes are pushed remove your App Builder Environment. +6. If your work is done and all changes are pushed remove your App Build Environment. -__Working in such a manner ensures that you are always working with the latest software components and avoids problems with the file size of your App Builder Environment. Furthermore creating backups is superfluous.__ +__Working in such a manner ensures that you are always working with the latest software components and avoids problems with the file size of your App Build Environment. Furthermore creating backups is superfluous.__ -## Create a Backup of your App Builder Environment +## Create a Backup of your App Build Environment -The file system of an App Builder Environment is loaded from two files. +The file system of an App Build Environment is loaded from two files. The first one is the Ubuntu cloud image file __ubuntu-20.04-server-cloudimg-amd64.img__ originally downloaded from which has a file size of about 600MB. This file is static - no changes are made during runtime or shutdown of your VM. So there is no need to handle it. @@ -23,12 +23,12 @@ The second one is the so called snapshot file __ubuntu-20.04-server-cloudimg-amd All changes are stored into the snapshot files. Our backup procedure handles this file. !!! important - Shutdown your App Builder Environment before you backup the qcow2 file. + Shutdown your App Build Environment before you backup the qcow2 file. __Prerequisites:__ The tool qemu-ing is installed by ctrlX WORKS. We assume that ctrlX WORKS is installed in "c:\Program Files\Rexroth\ctrlX WORKS\". If not use your specific installation path to call qemu-ing. -Open the storage location of your App Builder Environment. +Open the storage location of your App Build Environment. Rename the actual qcow2 file: @@ -42,4 +42,4 @@ Be patient this process takes some times. The convert process also removes unused blocks - so the new qcow2 file should be smaller than the bak file. -Start the App Builder Environment to test the new qcow2 file. \ No newline at end of file +Start the App Build Environment to test the new qcow2 file. \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index cad5c62d..2288ba9c 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -92,7 +92,7 @@ nav: - Guidelines: - Package Assets: package-assets.md - App Developer Guideline: appdevguide.md - - Data Persistance: persistdata.md + - App persist configurations: persistdata.md - License Management: licensing.md - Service-to-Service Authentication: s2sauth.md - Using Flatbuffers in IEC 61131-3 Code: fbs2plc.md @@ -108,10 +108,11 @@ nav: - QEMU Virtual Machine: setup_qemu_ubuntu.md - VirtualBox Virtual Machine: setup_windows_virtualbox_ubuntu.md - Native Ubuntu 20.04: setup_ubuntu.md + - Install Sources from github: install-sources-from-github.md - Toolchain: - Px.exe as Proxy on a Windows Host: px.md - Connecting QEMU VMs and ctrlX CORE: connecting_qemu_vm_ctrlx.md - - Working with App Builder Environments (QEMU VMs): working-with-app-builder-envs.md + - Working with App Build Environments (QEMU VMs): working-with-app-builder-envs.md - SSH Connection: ssh_connection.md - Visual Studio Code: vscode.md - .NET: dotnet.md diff --git a/samples-angular/.vscode/settings.json b/samples-angular/.vscode/settings.json new file mode 100644 index 00000000..3b664107 --- /dev/null +++ b/samples-angular/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "git.ignoreLimitWarning": true +} \ No newline at end of file diff --git a/samples-angular/README.md b/samples-angular/README.md new file mode 100644 index 00000000..d4876900 --- /dev/null +++ b/samples-angular/README.md @@ -0,0 +1,5 @@ +## Find out the supported samples + +### Basic Samples + +* [Hello Multilanguage ](./hello.multilanguage/README.md) \ No newline at end of file diff --git a/samples-angular/hello.multilanguage/.browserslistrc b/samples-angular/hello.multilanguage/.browserslistrc new file mode 100644 index 00000000..72df5cb8 --- /dev/null +++ b/samples-angular/hello.multilanguage/.browserslistrc @@ -0,0 +1,16 @@ +# This file is used by the build system to adjust CSS and JS output to support the specified browsers below. +# For additional information regarding the format and rule options, please see: +# https://github.com/browserslist/browserslist#queries + +# For the full list of supported browsers by the Angular framework, please see: +# https://angular.io/guide/browser-support + +# You can see what browsers were selected by your queries by running: +# npx browserslist + +last 1 Chrome version +last 1 Firefox version +last 2 Edge major versions +last 2 Safari major versions +last 2 iOS major versions +Firefox ESR \ No newline at end of file diff --git a/samples-angular/hello.multilanguage/.editorconfig b/samples-angular/hello.multilanguage/.editorconfig new file mode 100644 index 00000000..a9ca04de --- /dev/null +++ b/samples-angular/hello.multilanguage/.editorconfig @@ -0,0 +1,16 @@ +# Editor configuration, see https://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 4 +insert_final_newline = false +trim_trailing_whitespace = false + +[*.ts] +quote_type = single + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/samples-angular/hello.multilanguage/.gitignore b/samples-angular/hello.multilanguage/.gitignore new file mode 100644 index 00000000..ecd12773 --- /dev/null +++ b/samples-angular/hello.multilanguage/.gitignore @@ -0,0 +1,42 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. + +# Compiled output +/dist +/tmp +/out-tsc +/bazel-out + +# Node +/node_modules + +# IDEs and editors +.idea/ +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# Visual Studio Code +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +.history/* + +# Miscellaneous +/.angular/cache +.sass-cache/ +/connect.lock +/coverage +/libpeerconnection.log +npm-debug.log +yarn-error.log +testem.log +/typings + +# System files +.DS_Store +Thumbs.db diff --git a/samples-angular/hello.multilanguage/.vscode/extensions.json b/samples-angular/hello.multilanguage/.vscode/extensions.json new file mode 100644 index 00000000..fc2424d2 --- /dev/null +++ b/samples-angular/hello.multilanguage/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["angular.ng-template"] +} \ No newline at end of file diff --git a/samples-angular/hello.multilanguage/.vscode/launch.json b/samples-angular/hello.multilanguage/.vscode/launch.json new file mode 100644 index 00000000..98b29144 --- /dev/null +++ b/samples-angular/hello.multilanguage/.vscode/launch.json @@ -0,0 +1,19 @@ +{ + "version": "0.0.1", + "configurations": [ + { + "name": "ng serve", + "type": "pwa-chrome", + "request": "launch", + "preLaunchTask": "npm: start", + "url": "http://localhost:4200/" + }, + { + "name": "ng test", + "type": "chrome", + "request": "launch", + "preLaunchTask": "npm: test", + "url": "http://localhost:9876/debug.html" + } + ] +} diff --git a/samples-angular/hello.multilanguage/.vscode/settings.json b/samples-angular/hello.multilanguage/.vscode/settings.json new file mode 100644 index 00000000..60de63bb --- /dev/null +++ b/samples-angular/hello.multilanguage/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "files.autoSave": "afterDelay", + "html.format.wrapAttributes": "force-aligned" +} \ No newline at end of file diff --git a/samples-angular/hello.multilanguage/.vscode/tasks.json b/samples-angular/hello.multilanguage/.vscode/tasks.json new file mode 100644 index 00000000..be83fe8f --- /dev/null +++ b/samples-angular/hello.multilanguage/.vscode/tasks.json @@ -0,0 +1,97 @@ +{ + // For more information, visit: https://go.microsoft.com/fwlink/?LinkId=733558 + "version": "2.0.0", + "tasks": [ + { + "label": "build snap amd64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-amd64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": true + } + }, + { + "label": "build snap arm64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-arm64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": true + } + }, + { + "label": "npm clean", + "group": { + "kind": "build", + "isDefault": true + }, + "type": "shell", + "problemMatcher": [], + "command": "rm -rf node_modules", + "options": { + "cwd": "${workspaceFolder}" + } + }, + { + "label": "npm install", + "group": { + "kind": "build", + "isDefault": true + }, + "type": "shell", + "problemMatcher": [], + "command": "npm install", + "options": { + "cwd": "${workspaceFolder}" + }, + "dependsOn": [ + "npm clean" + ] + }, + { + "type": "npm", + "script": "start", + "isBackground": true, + "problemMatcher": { + "owner": "typescript", + "pattern": "$tsc", + "background": { + "activeOnStart": true, + "beginsPattern": { + "regexp": "(.*?)" + }, + "endsPattern": { + "regexp": "bundle generation complete" + } + } + } + }, + { + "type": "npm", + "script": "test", + "isBackground": true, + "problemMatcher": { + "owner": "typescript", + "pattern": "$tsc", + "background": { + "activeOnStart": true, + "beginsPattern": { + "regexp": "(.*?)" + }, + "endsPattern": { + "regexp": "bundle generation complete" + } + } + } + } + ] +} diff --git a/samples-angular/hello.multilanguage/README.md b/samples-angular/hello.multilanguage/README.md new file mode 100644 index 00000000..6f82bbdf --- /dev/null +++ b/samples-angular/hello.multilanguage/README.md @@ -0,0 +1,363 @@ +# README hello.multilanguage.angular + +This Hello Multilanguage sample is an Angular application to demonstrate the use of localization files in ctrlX apps. + +## Introduction + +We use the _NGX-Translate_ library to localize our webapps. +Details of this library can be found here: http://www.ngx-translate.com/ + +The basic concept of __localization__ is to extract __localizable texts__ from HTML and Type Script and to put them into language specific localization files. +At runtime localized texts are loaded from localization files depending on the currently selected language and displayes within the UI. + +## Localization Files + +### Concept and Notation +All texts to translate are stored in json __localization files__. +Localization files are loaded at runtime from: __https:///assets/i18n/__ + ++ To ensure that several localization files can be located in the assets directory in parallel, they have to comply to the following naming convention: + __webAppName.(lang-ISO_639-1-code).json__ ++ Localization files contain localizable texts for exactly one language and for exactly one webapp. ++ For ISO codes refer to https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes + + ```bash + Example: + myApp.en.json + myApp.de.json + +#### Content and structure + +Localization files are basically _key/values_ lists. Each _key/value_ pair represents one localizable string. + +The basic format of a key/value entry is: + + "": "" + +### Key naming convention + +Keys have to comply the following convention to avoid conflicts when several localization files are loaded simultaneously at runtime: + + (webApp id).(component).(element)[.type] + ++ _webapp id_: to make keys unique across all webapps and id has to be part of a key (e.g. "plc", "wrk", "frw" ,"idm"...) ++ _component_: denotes the building block (angular component, service etc.) within a webapp where the translatable text is located (e.g. login-dialog,control-details,common-texts...) ++ _element_: denotes the ui-element within a component on which the text is placed (e.g. connectionfailed, userimage, acceleration...) ++ _type_: denotes the type of the ui-element. This gives translators additional information that is relevant for translation. It is only required for the certain ui-element types + + ```bash + title (page / dialog titles) + header (column headers etc.) + tab (tab page titles) + menu (sidebar menus and other menus) + sub menu (sidebar menus and other menus) + button (button text) + tooltip (tooltip text max length?) + +### Localization file formats +There are two formats of localization files: the flat format and the namespaced format. + +_Flat format_ + +In flat format each key/value pair corresponds to one line within the json file. + +The flat format is the straight forward approach that can be used especially in small webapps that do not have much translatable text. +This is quite simple. Though with increasing file length it becomes difficult to keep overview about the file content. + + Example + { + "frw.configStartPage.packetFlowOverview": "Packet flow overview", + "frw.configStartPage.configurePacketFiltering": "Configure packet filtering", + "frw.configStartPage.configureNat": "Configure network address translation" + } + +or + + { + "wrk.settings.title": "Setting", + "wrk.settings.help.header": "Help", + "wrk.settings.control-emulation.header": "Virtual control emulation", + "wrk.settings.control-emulation.tooltip": "Only evaluated when starting a control", + "wrk.settings.control-emulation": "Show the emulation process window for a running ctrlX COREvirtual" + } + +_Namespaced format_ + +To add structure to extensive localization files the namespaced format can be used. + +In this format the effective key (e.g. "frw.configStartPage.packetFlowOverview") will be composed of the namespace (e.g. "frw.configStartPage) and the key within the namespace (e.g. "packetFlowOverview"). +This means that both formats are equivalent and represent the same localization information. + + Example: + { + "frw.configStartPage": { + "packetFlowOverview": "Packet flow overview", + "configurePacketFiltering": "Configure packet filtering", + "configureNat": "Configure network address translation" + } + } + +or + + { + "wrk.settings": { + "title": "Setting", + "help.header": "Help", + "control-emulation.header": "Virtual control emulation", + "control-emulation.tooltip": "Only evaluated when starting a control", + "control-emulation": "Show the emulation process window for a running ctrlX COREvirtual" + } + +_IMPORTANT_ + +Only add texts to be translated in the file. Texts that should not be translated do not belong in the translation file. + +It is not possible to add comments into to a translation file. + + +## Responsibilites of webapps regarding localization + +WebApps ++ are responsible to comply naming conventions for localization files ++ are responsible to transfer the localization files of their used weblibs to their own assets folder (angular.json => glob) ++ are responsible to load their own localization files as well as the localization files of their used weblibs (app.module.ts => _TranslationModule_, _MultiTranslateHttpLoader_) ++ are responsible to set the current language as well as the fallback language + +## __How to make webapps localizable__ + +### __Install ngx-translate and ngx-translate-multi-http-loader__ +Use the following commands to install ngx-translate and ngx-translate-multi-http-loader: + + npm install @ngx-translate/core @ngx-translate/http-loader rxjs --save + npm install ngx-translate-multi-http-loader --save + +### __Add an assets/i18n folder to your webapp project__ +Add the assets-folder within the src-folder in webapps, as listed below: + + |- + |- src <= sources are here + |- assets + | |- i18n <= localization files are located here + | |- .en.json + | |- .de.json| + |- app ... + +### __Add the assets folder of weblibs used in the webapp to the assets array in angular.json__ + + { + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + ... + "projects": { + "webapp.": { + ... + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:browser", + "options": { + "outputPath": "dist/", + "index": "src/index.html", + "main": "src/main.ts", + "polyfills": "src/polyfills.ts", + "tsConfig": "tsconfig.app.json", + "baseHref": "/webapp./", + ... + "assets": [ + "src/assets" + ], + styles": [ + "src/styles.scss" + ], + "scripts": [] + }, + ... + } + +### __Add the TranslateModule to app.module.ts__ + + import { TranslateModule, TranslateLoader } from '@ngx-translate/core'; + import { MultiTranslateHttpLoader } from 'ngx-translate-multi-http-loader'; + + export function createMultiTranslateHttpLoader(http: HttpClient): TranslateLoader { + return new MultiTranslateHttpLoader(http, [ + + //This is how it goes for apps that uses lazy loaded modules (example: firewall app) + { prefix: './/assets/i18n/.', suffix: '.json' }, <= add this for the webapp + { prefix: './/assets/i18n/.', suffix: '.json' }, <= add this for the webapp + { prefix: './assets/i18n/.module.ts + + import { HttpClientModule} from '@angular/common/http'; + import { TranslateModule } from '@ngx-translate/core'; + + @NgModule({ + declarations: [ + ... + ], + imports: [ + ..., + HttpClientModule, + TranslateModule.forChild({ + extend: true + }), + ... + ], + +_NOTE_ + +Note that in feature modules TranslateModule.forChild() must be called. +### Localize the UI related parts of your webapp +Please see details here: https://github.com/ngx-translate/core + +### Add the TranslateModule for unit tests +Because of injected translate service it is necessary to modify unit tests of app.component (app.component.spec.ts) and other components (.component.spec.ts). + +It is also very important to make the change in the "app-routing.module.spec.ts" as well. + + import { TranslateModule} from '@ngx-translate/core'; + + describe('AppComponent', () => { + ... + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + imports: [ + ..., + TranslateModule.forRoot(), // This is sufficcient. Note that only the text keys are displayed when unit tests are executed. + ... + ], + ... + }) + .compileComponents(); + })); + +## Translation process + +The json language file can be translated using common translation tools like Passolo or BabelEdit. + +## 7. Enable locale specific formatting with the angular pipe operators + +### Problem +I need to format a long decimal number with thousand separators (123456789 → 123.456.789, assuming de-DE formatting).
+When I use the Angular DecimalPipe I get "123,456,789" as a result regardless of the language settings (DE or EN) in the ctrlX app.
+ +I tried to supply a locale to the DecimalPipe like this: + + {{ item.sum | number:'0.0-0':'de-DE'}} + +The idea here is to provide a locale derived from the value of currentLang of the TranslateService. + +I get the error: + +_ERROR Error: NG02100: InvalidPipeArgument: 'Missing locale data for the locale "de-DE".' for pipe 'DecimalPipe'._ + +The reason for this error seems to be a missing registration for the locale de-DE
+It seems that at the moment there is no general guideline on how to handle locale aware formatting within our application. +### Expected behavior +When the user changes between languages in the ctrlX app, the formatting of numbers and dates is influcenced by that change.
+As a developer I can use the standard Angular pipes like DecimalPipe and the formatting of the output respects the current language selection.
+This must be managed globally. This is not a responsibility of a single feature module.
+As there are multiple locales per language (e.g. en-US, en-GB) , we must either decide on a fixed locale per language or we must provide the user with the ability to select the locale in addition to the language. +### Solution +After some research here is a possible solution. It involves the following steps. + ++ Register a provider that will a provide a value of the LOCALE_ID that is based on the currently selected language. ++ Register the localeData for the German language. + +Here are the changes necessary to make this work. Everything is located in the app.module file. + + import { APP_INITIALIZER, LOCALE_ID, NgModule} from '@angular/core'; + import { registerLocaleData } from "@angular/common"; + import localeDe from "@angular/common/locales/de"; + + @NgModule({ + declarations: [ + // existing code omitted + ], + imports: [ + // existing code omitted + ], + providers: [ + { + // existing code omitted + }, { + provide: LOCALE_ID, + deps: [TranslateService], + useFactory: (translateService: TranslateService) => translateService.currentLang + } + ], + bootstrap: [AppComponent] + }) + + export class AppModule { + constructor() { + registerLocaleData(localeDe); + } + } + + + + +## Gratulations - We're finished - Let's start coding! + +## Support +### Developer Community + +Please join the [Developer Community](https://developer.community.boschrexroth.com/) + +### SDK Forum + +Please visit the [SDK Forum](https://developer.community.boschrexroth.com/t5/ctrlX-AUTOMATION/ct-p/dcdev_community-bunit-dcae/) + +### Issues + +If you've found an error in these sample, please [file an issue](https://github.com/boschrexroth) + +## License + +MIT License + +Copyright (c) 2021 Bosch Rexroth AG + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/samples-angular/hello.multilanguage/angular.json b/samples-angular/hello.multilanguage/angular.json new file mode 100644 index 00000000..a88c9038 --- /dev/null +++ b/samples-angular/hello.multilanguage/angular.json @@ -0,0 +1,118 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "newProjectRoot": "projects", + "projects": { + "multilanguage": { + "projectType": "application", + "schematics": { + "@schematics/angular:component": { + "style": "scss" + } + }, + "root": "", + "sourceRoot": "src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:browser", + "options": { + "outputPath": "dist/app", + "index": "src/index.html", + "main": "src/main.ts", + "polyfills": "src/polyfills.ts", + "tsConfig": "tsconfig.app.json", + "assets": [ + "src/favicon.ico", + "src/assets" + ], + "styles": [ + "src/styles.scss" + ], + "scripts": [], + "baseHref": "/ctrlx-hello-multilanguage/" + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "512mb", + "maximumError": "512mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "512mb", + "maximumError": "512mb" + } + ], + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.prod.ts" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "builder": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "browserTarget": "multilanguage:build:production" + }, + "development": { + "browserTarget": "multilanguage:build:development" + } + }, + "defaultConfiguration": "development" + }, + "extract-i18n": { + "builder": "@angular-devkit/build-angular:extract-i18n", + "options": { + "browserTarget": "multilanguage:build" + } + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "main": "src/test.ts", + "polyfills": "src/polyfills.ts", + "tsConfig": "tsconfig.spec.json", + "karmaConfig": "karma.conf.js", + "assets": [ + "src/favicon.ico", + "src/assets" + ], + "styles": [ + "src/styles.scss" + ], + "scripts": [] + } + }, + "lint": { + "builder": "@angular-eslint/builder:lint", + "options": { + "lintFilePatterns": [ + "src/**/*.ts", + "src/**/*.html" + ] + } + } + } + } + }, + "cli": { + "defaultCollection": "@angular-eslint/schematics" + } +} diff --git a/samples-angular/hello.multilanguage/build-snap-amd64.sh b/samples-angular/hello.multilanguage/build-snap-amd64.sh new file mode 100644 index 00000000..d090a57a --- /dev/null +++ b/samples-angular/hello.multilanguage/build-snap-amd64.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +snapcraft clean --destructive-mode +snapcraft --destructive-mode --target-arch=amd64 --enable-experimental-target-arch \ No newline at end of file diff --git a/samples-angular/hello.multilanguage/build-snap-arm64.sh b/samples-angular/hello.multilanguage/build-snap-arm64.sh new file mode 100644 index 00000000..b41b7fd2 --- /dev/null +++ b/samples-angular/hello.multilanguage/build-snap-arm64.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +snapcraft clean --destructive-mode +snapcraft --destructive-mode --target-arch=arm64 --enable-experimental-target-arch \ No newline at end of file diff --git a/samples-angular/hello.multilanguage/configs/package-assets/ctrlx-hello-multilanguage.package-manifest.json b/samples-angular/hello.multilanguage/configs/package-assets/ctrlx-hello-multilanguage.package-manifest.json new file mode 100644 index 00000000..3e6cb9c2 --- /dev/null +++ b/samples-angular/hello.multilanguage/configs/package-assets/ctrlx-hello-multilanguage.package-manifest.json @@ -0,0 +1,24 @@ +{ + "version": "1.0.0", + "id": "ctrlx-hello-multilanguage", + "menus": { + "sidebar": [ + { + "id": "ctrlx-hello-multilanguage", + "title": "Hello Multilanguage", + "icon": "bosch-ic-translate", + "link": "/ctrlx-hello-multilanguage", + "target": "_blank" + } + ] + }, + "services": { + "proxyMapping": [ + { + "binding": "unix://{$PACKAGE_WWW_SOCKET}", + "name": "ctrlx-hello-multilanguage", + "url": "/ctrlx-hello-multilanguage" + } + ] + } +} \ No newline at end of file diff --git a/samples-angular/hello.multilanguage/karma.conf.js b/samples-angular/hello.multilanguage/karma.conf.js new file mode 100644 index 00000000..57d5d8d6 --- /dev/null +++ b/samples-angular/hello.multilanguage/karma.conf.js @@ -0,0 +1,59 @@ +// Karma configuration file, see link for more information +// https://karma-runner.github.io/1.0/config/configuration-file.html + +module.exports = function (config) { + config.set({ + basePath: '', + frameworks: ['jasmine', '@angular-devkit/build-angular'], + plugins: [ + require('karma-jasmine'), + require('karma-chrome-launcher'), + require('karma-jasmine-html-reporter'), + require('karma-coverage'), + require('@angular-devkit/build-angular/plugins/karma') + ], + client: { + clearContext: false // leave Jasmine Spec Runner output visible in browser + }, + coverageReporter: { + dir: require('path').join(__dirname, './coverage'), + reporters: [ + {type: 'html', subdir: '.'}, + {type: 'lcovonly', subdir: '.'} + ], + fixWebpackSourcePaths: true, + thresholds: { + statements: 50, + lines: 50, + branches: 10, + functions: 40 + } + }, + reporters: ['progress', 'kjhtml'], + port: 9876, + colors: true, + logLevel: config.LOG_INFO, + autoWatch: true, + browsers: ['Chrome', 'Chrome_NoSandbox', 'ChromeHeadless', 'ChromeHeadless_NoSandbox'], + singleRun: false, + restartOnFileChange: true, + browserDisconnectTolerance: 2, + browserDisconnectTimeout: 50000, + browserNoActivityTimeout: 20000, + customLaunchers: { + Chrome_NoSandbox: { + base: 'Chrome', + flags: ['--no-sandbox'] + }, + ChromeHeadless_NoSandbox: { + base: 'ChromeHeadless', + flags: ['--no-sandbox'] + }, + Chrome_with_debugging: { + base: 'Chrome', + flags: ['--remote-debugging-port=9222'], + debug: true + } + } + }); +}; diff --git a/samples-angular/hello.multilanguage/package.json b/samples-angular/hello.multilanguage/package.json new file mode 100644 index 00000000..ae31f45e --- /dev/null +++ b/samples-angular/hello.multilanguage/package.json @@ -0,0 +1,37 @@ +{ + "name": "multilanguage", + "version": "0.0.1", + "scripts": { + "ng": "ng", + "start": "ng serve -o", + "build": "ng build", + "watch": "ng build --watch --configuration development", + "test": "ng test" + }, + "private": true, + "dependencies": { + "@angular/animations": "~13.3.11", + "@angular/cdk": "^13.3.9", + "@angular/common": "~13.3.11", + "@angular/compiler": "~13.3.11", + "@angular/core": "~13.3.11", + "@angular/forms": "~13.3.11", + "@angular/material": "^13.3.9", + "@angular/platform-browser": "~13.3.11", + "@angular/platform-browser-dynamic": "~13.3.11", + "@ngx-translate/core": "^14.0.0", + "@ngx-translate/http-loader": "^7.0.0", + "ngx-translate-multi-http-loader": "^7.0.5", + "snap": "^1.1.0", + "tslib": "^2.0.0", + "zone.js": "^0.12.0" + }, + "devDependencies": { + "@angular-devkit/build-angular": "^13.3.6", + "@angular/cli": "~13.3.8", + "@angular/compiler-cli": "~13.3.9", + "@types/node": "^18.11.9", + "ngx-translate-extract": "^1.0.0", + "typescript": "~4.6.2" + } +} diff --git a/samples-angular/hello.multilanguage/snap/snapcraft.yaml b/samples-angular/hello.multilanguage/snap/snapcraft.yaml new file mode 100644 index 00000000..c80394c8 --- /dev/null +++ b/samples-angular/hello.multilanguage/snap/snapcraft.yaml @@ -0,0 +1,55 @@ +# See https://snapcraft.io/docs/getting-started +# See https://snapcraft.io/docs/snapcraft-yaml-reference +name: ctrlx-hello-multilanguage +version: '1.0.0' +base: core20 +title: Hello Multilanguage +summary: Multilanguage sample in Angular for ctrlX +description: | + This programm shows how to set differen languages in Third-party apps. +grade: stable # must be 'stable' to release into candidate/stable channels +confinement: strict # reduced file access to selected areas, reduced + +parts: + configs: + source: ./configs + plugin: dump + organize: + 'package-assets/*': package-assets/${SNAPCRAFT_PROJECT_NAME}/ + + www: + source: . + plugin: npm + npm-node-version: '14.15.0' + override-build: | + # install node + snapcraftctl build + + # setup npm + npm config set unsafe-perm true + + # install dependencies + npm install + + # run angular build script + npm run build + + # remove node + rm -rf ${SNAPCRAFT_PART_INSTALL} + organize: + '${SNAPCRAFT_PART_BUILD}/dist/app': package-www/${SNAPCRAFT_PROJECT_NAME}/ + +slots: + package-assets: + interface: content + content: package-assets + source: + read: + - $SNAP/package-assets/${SNAPCRAFT_PROJECT_NAME} + + package-www: + interface: content + content: package-www + source: + read: + - $SNAP/package-www/${SNAPCRAFT_PROJECT_NAME} diff --git a/samples-angular/hello.multilanguage/src/app/app.component.html b/samples-angular/hello.multilanguage/src/app/app.component.html new file mode 100644 index 00000000..445fe5a2 --- /dev/null +++ b/samples-angular/hello.multilanguage/src/app/app.component.html @@ -0,0 +1,3 @@ +
+ +
diff --git a/samples-angular/hello.multilanguage/src/app/app.component.scss b/samples-angular/hello.multilanguage/src/app/app.component.scss new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/samples-angular/hello.multilanguage/src/app/app.component.scss @@ -0,0 +1 @@ + diff --git a/samples-angular/hello.multilanguage/src/app/app.component.spec.ts b/samples-angular/hello.multilanguage/src/app/app.component.spec.ts new file mode 100644 index 00000000..19c4be85 --- /dev/null +++ b/samples-angular/hello.multilanguage/src/app/app.component.spec.ts @@ -0,0 +1,35 @@ +import { TestBed } from '@angular/core/testing'; +import { AppComponent } from './app.component'; +import { TranslateModule} from '@ngx-translate/core'; +import { TranslateService } from '@ngx-translate/core'; + +describe('AppComponent', () => { + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ + AppComponent, + TranslateService + ], + providers: [ TranslateService], + }).compileComponents(); + }); + + it('should create the app', () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.componentInstance; + expect(app).toBeTruthy(); + }); + + it(`should have as title 'Angular: Hello Multilanguage'`, () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.componentInstance; + expect(app.title).toEqual('Angular: Hello Multilanguage'); + }); + + it('should render title', () => { + const fixture = TestBed.createComponent(AppComponent); + fixture.detectChanges(); + const compiled = fixture.nativeElement as HTMLElement; + expect(compiled.querySelector('h1').textContent).toContain('Welcome to Angular: Hello Multilanguage!'); + }); +}); diff --git a/samples-angular/hello.multilanguage/src/app/app.component.ts b/samples-angular/hello.multilanguage/src/app/app.component.ts new file mode 100644 index 00000000..9a8db0f2 --- /dev/null +++ b/samples-angular/hello.multilanguage/src/app/app.component.ts @@ -0,0 +1,9 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-root', + templateUrl: './app.component.html', + styleUrls: ['./app.component.scss'] +}) +export class AppComponent { +} diff --git a/samples-angular/hello.multilanguage/src/app/app.module.ts b/samples-angular/hello.multilanguage/src/app/app.module.ts new file mode 100644 index 00000000..e85fe123 --- /dev/null +++ b/samples-angular/hello.multilanguage/src/app/app.module.ts @@ -0,0 +1,48 @@ +import { NgModule, APP_INITIALIZER } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { FormsModule } from '@angular/forms'; +import { AppComponent } from './app.component'; +import { ProductListComponent } from './books/book-list.component'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { MatTableModule } from '@angular/material/table' +import { MatButtonToggleModule } from '@angular/material/button-toggle'; +import { MatButtonModule } from '@angular/material/button'; + +// import ngx-translate and the http loader +import { TranslateModule, TranslateLoader } from '@ngx-translate/core'; +import { MultiTranslateHttpLoader } from 'ngx-translate-multi-http-loader'; +import { HttpClient, HttpClientModule } from '@angular/common/http'; + +export function createMultiTranslateHttpLoader(http: HttpClient): TranslateLoader { + return new MultiTranslateHttpLoader(http, [ + { prefix: './assets/i18n/multilanguage.', suffix: '.json' } + ]); +} + +@NgModule({ + declarations: [ + AppComponent, + ProductListComponent + ], + imports: [ + BrowserModule, + HttpClientModule, + FormsModule, + MatTableModule, + MatButtonModule, + MatButtonToggleModule, + TranslateModule.forRoot({ + loader: { + provide: TranslateLoader, + useFactory: createMultiTranslateHttpLoader, + deps: [HttpClient] + }, + defaultLanguage: 'en' + }), + BrowserAnimationsModule, + ], + providers: [ + ], + bootstrap: [AppComponent] +}) +export class AppModule { } \ No newline at end of file diff --git a/samples-angular/hello.multilanguage/src/app/books/book-list.component.html b/samples-angular/hello.multilanguage/src/app/books/book-list.component.html new file mode 100644 index 00000000..5c461f8c --- /dev/null +++ b/samples-angular/hello.multilanguage/src/app/books/book-list.component.html @@ -0,0 +1,44 @@ +
+
+

{{'doc.pageTitle' | translate}}

+

{{'doc.title' | translate}}

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{{'doc.table.id' | translate}} {{book.id}} {{'doc.table.author' | translate}} {{book.author}} {{'doc.table.title' | translate}} {{book.title | translate}} {{'doc.table.category' | translate}} {{book.category | translate}} {{'doc.table.price' | translate}} {{book.price | currency:'EUR':'symbol':'1.2-2' }}
+ +
+ + + +
+
+
\ No newline at end of file diff --git a/samples-angular/hello.multilanguage/src/app/books/book-list.component.scss b/samples-angular/hello.multilanguage/src/app/books/book-list.component.scss new file mode 100644 index 00000000..fa70657e --- /dev/null +++ b/samples-angular/hello.multilanguage/src/app/books/book-list.component.scss @@ -0,0 +1,58 @@ +.sample-header { + font-size: large; + text-align: center; + margin-top: 20px; + background-image: linear-gradient( rgb(126, 189, 221), white,); +} + +.table { + width: 100%; + table-layout: fixed; + } + +.mat-raised-button { + margin:30px 0px 0px 0px; + padding:10px; + display: flex; + justify-content: center; + align-items: center; + width: 100px; + height: 30px; + background: rgb(126, 189, 221); + color:black; +} + +.mat-header-cell { + font-size: large; + font-weight: bold; +} + +.mat-column-id { + width: 30px; + padding-right: 14px; + text-align: center; +} + +.mat-column-author { + width: 60px; + padding-left: 16px; + text-align: center; +} + +.mat-column-title { + width: 60px; + padding-left: 16px; + text-align: center; +} + +.mat-column-category { + width: 60px; + padding-left: 16px; + text-align: center; +} + +.mat-column-price { + width: 60px; + padding-left: 16px; + text-align: center; +} \ No newline at end of file diff --git a/samples-angular/hello.multilanguage/src/app/books/book-list.component.spec.ts b/samples-angular/hello.multilanguage/src/app/books/book-list.component.spec.ts new file mode 100644 index 00000000..73903c89 --- /dev/null +++ b/samples-angular/hello.multilanguage/src/app/books/book-list.component.spec.ts @@ -0,0 +1,46 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { RouterModule } from '@angular/router' +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; +import { TranslateModule, TranslateService } from '@ngx-translate/core'; +import { ProductListComponent } from './book-list.component' + + +describe('ProductListComponent', () => { + let fixture: ComponentFixture; + let component: ProductListComponent; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports:[ + BrowserAnimationsModule, + HttpClientTestingModule, + TranslateModule.forRoot(), + RouterModule.forRoot([], { relativeLinkResolution: 'legacy' }) + ], + declarations: [ ProductListComponent ], + providers: [ + TranslateService, + ], + schemas:[ NO_ERRORS_SCHEMA ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(ProductListComponent); + component = fixture.componentInstance; + + fixture.detectChanges(); + }); + + afterEach(() => { + fixture.destroy(); + }); + + describe('Component', ()=> { + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); \ No newline at end of file diff --git a/samples-angular/hello.multilanguage/src/app/books/book-list.component.ts b/samples-angular/hello.multilanguage/src/app/books/book-list.component.ts new file mode 100644 index 00000000..cf063de2 --- /dev/null +++ b/samples-angular/hello.multilanguage/src/app/books/book-list.component.ts @@ -0,0 +1,82 @@ +import { AfterViewInit, Component } from '@angular/core'; +import { TranslateService } from '@ngx-translate/core'; +import { IBook } from './book'; + +@Component({ + selector: 'app-books', + templateUrl: './book-list.component.html', + styleUrls: ['./book-list.component.scss'], +}) +export class ProductListComponent implements AfterViewInit { + language = 'en'; + myColumns = ['id', 'author', 'title', 'category', 'price']; + isEnglish = false; + isGerman = false; + + constructor(private translate: TranslateService) { + translate.use(this.language); + } + + ngAfterViewInit() { + this.enLanguage(); + } + + deLanguage() { + this.language = 'de'; + this.isGerman = true; + this.isEnglish = false; + this.translate.use('de'); + } + + enLanguage() { + this.language = 'en'; + this.isEnglish = true; + this.isGerman = false; + this.translate.use('en'); + } + + books: IBook[] = [ + { + id: 1, + author: 'Agatha Christie', + title: 'doc.book.Title-1', + category: 'doc.book.Category-1', + price: 16.45, + }, + { + id: 2, + author: 'Rosamunde Pilcher', + title: 'doc.book.Title-2', + category: 'doc.book.Category-2', + price: 12.51, + }, + { + id: 3, + author: 'J. R. R. Tolkien', + title: 'doc.book.Title-3', + category: 'doc.book.Category-3', + price: 72.98, + }, + { + id: 4, + author: 'Brian Johnson', + title: 'doc.book.Title-4', + category: 'doc.book.Category-4', + price: 29.95, + }, + { + id: 5, + author: 'Matthew Ray Russell', + title: 'doc.book.Title-5', + category: 'doc.book.Category-5', + price: 25.71, + }, + { + id: 6, + author: 'Rob Brunia', + title: 'doc.book.Title-6', + category: 'doc.book.Category-6', + price: 11.39, + }, + ]; +} diff --git a/samples-angular/hello.multilanguage/src/app/books/book.ts b/samples-angular/hello.multilanguage/src/app/books/book.ts new file mode 100644 index 00000000..9cc917f5 --- /dev/null +++ b/samples-angular/hello.multilanguage/src/app/books/book.ts @@ -0,0 +1,7 @@ +export interface IBook { + id : number; + author: string; + title: string; + category: string; + price: number; +} \ No newline at end of file diff --git a/samples-net/datalayer.client/test.cs b/samples-angular/hello.multilanguage/src/assets/.gitkeep similarity index 100% rename from samples-net/datalayer.client/test.cs rename to samples-angular/hello.multilanguage/src/assets/.gitkeep diff --git a/samples-angular/hello.multilanguage/src/assets/i18n/multilanguage.de.json b/samples-angular/hello.multilanguage/src/assets/i18n/multilanguage.de.json new file mode 100644 index 00000000..148cec21 --- /dev/null +++ b/samples-angular/hello.multilanguage/src/assets/i18n/multilanguage.de.json @@ -0,0 +1,27 @@ +{ + "doc": { + "pageTitle": "Multilanguage in ctrlX", + "title": "Das ist eine Beispielanwendung für die Nutzung von ngx-translate", + "table": { + "id": "Nummer", + "author": "Autor", + "title": "Titel", + "category": "Kategorie", + "price": "Preis" + }, + "book": { + "Title-1": "Hercule Poirot", + "Category-1": "Krimi", + "Title-2": "September", + "Category-2": "Liebesroman", + "Title-3": "Der Herr der Ringe", + "Category-3": "Fantasie", + "Title-4": "Die Leben des Brian", + "Category-4": "Biografie", + "Title-5": "Daytrading", + "Category-5": "Ratgeber", + "Title-6": "Schach", + "Category-6": "Fachbuch" + } + } +} diff --git a/samples-angular/hello.multilanguage/src/assets/i18n/multilanguage.en.json b/samples-angular/hello.multilanguage/src/assets/i18n/multilanguage.en.json new file mode 100644 index 00000000..ee4abc67 --- /dev/null +++ b/samples-angular/hello.multilanguage/src/assets/i18n/multilanguage.en.json @@ -0,0 +1,27 @@ +{ + "doc": { + "pageTitle": "Multilanguage in ctrlX", + "title": "This is an example application for the usage of ngx-translate", + "table": { + "id": "Id", + "author": "Author ", + "title": "Title", + "category": "Category", + "price": "Price" + }, + "book": { + "Title-1": "Hercule Poirot", + "Category-1": "Detective story", + "Title-2": "September", + "Category-2": "Romance novel", + "Title-3": "The Lord of the Rings", + "Category-3": "Fantasy", + "Title-4": "The Lives of Brian", + "Category-4": "Biography", + "Title-5": "Daytrading", + "Category-5": "Guidebook", + "Title-6": "Chess", + "Category-6": "Reference book" + } + } +} diff --git a/samples-angular/hello.multilanguage/src/environments/environment.prod.ts b/samples-angular/hello.multilanguage/src/environments/environment.prod.ts new file mode 100644 index 00000000..babe05e3 --- /dev/null +++ b/samples-angular/hello.multilanguage/src/environments/environment.prod.ts @@ -0,0 +1,3 @@ +export const environment = { + production: true +}; \ No newline at end of file diff --git a/samples-angular/hello.multilanguage/src/environments/environment.ts b/samples-angular/hello.multilanguage/src/environments/environment.ts new file mode 100644 index 00000000..9923be36 --- /dev/null +++ b/samples-angular/hello.multilanguage/src/environments/environment.ts @@ -0,0 +1,3 @@ +export const environment = { + production: false +}; \ No newline at end of file diff --git a/samples-angular/hello.multilanguage/src/favicon.ico b/samples-angular/hello.multilanguage/src/favicon.ico new file mode 100644 index 00000000..e69de29b diff --git a/samples-angular/hello.multilanguage/src/index.html b/samples-angular/hello.multilanguage/src/index.html new file mode 100644 index 00000000..6d274e46 --- /dev/null +++ b/samples-angular/hello.multilanguage/src/index.html @@ -0,0 +1,18 @@ + + + + + + Multilanguage Sample + + + + + + + + diff --git a/samples-angular/hello.multilanguage/src/main.ts b/samples-angular/hello.multilanguage/src/main.ts new file mode 100644 index 00000000..b31d8ef0 --- /dev/null +++ b/samples-angular/hello.multilanguage/src/main.ts @@ -0,0 +1,12 @@ +import { enableProdMode } from '@angular/core'; +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; +import { environment } from './environments/environment'; + +if (environment.production) { + enableProdMode(); +} + +platformBrowserDynamic().bootstrapModule(AppModule) + .catch(err => console.error(err)); \ No newline at end of file diff --git a/samples-angular/hello.multilanguage/src/polyfills.ts b/samples-angular/hello.multilanguage/src/polyfills.ts new file mode 100644 index 00000000..429bb9ef --- /dev/null +++ b/samples-angular/hello.multilanguage/src/polyfills.ts @@ -0,0 +1,53 @@ +/** + * This file includes polyfills needed by Angular and is loaded before the app. + * You can add your own extra polyfills to this file. + * + * This file is divided into 2 sections: + * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. + * 2. Application imports. Files imported after ZoneJS that should be loaded before your main + * file. + * + * The current setup is for so-called "evergreen" browsers; the last versions of browsers that + * automatically update themselves. This includes recent versions of Safari, Chrome (including + * Opera), Edge on the desktop, and iOS and Chrome on mobile. + * + * Learn more in https://angular.io/guide/browser-support + */ + +/*************************************************************************************************** + * BROWSER POLYFILLS + */ + +/** + * By default, zone.js will patch all possible macroTask and DomEvents + * user can disable parts of macroTask/DomEvents patch by setting following flags + * because those flags need to be set before `zone.js` being loaded, and webpack + * will put import in the top of bundle, so user need to create a separate file + * in this directory (for example: zone-flags.ts), and put the following flags + * into that file, and then add the following code before importing zone.js. + * import './zone-flags'; + * + * The flags allowed in zone-flags.ts are listed here. + * + * The following flags will work for all browsers. + * + * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame + * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick + * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames + * + * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js + * with the following flag, it will bypass `zone.js` patch for IE/Edge + * + * (window as any).__Zone_enable_cross_context_check = true; + * + */ + +/*************************************************************************************************** + * Zone JS is required by default for Angular itself. + */ +import 'zone.js'; // Included with Angular CLI. + + +/*************************************************************************************************** + * APPLICATION IMPORTS + */ diff --git a/samples-angular/hello.multilanguage/src/styles.scss b/samples-angular/hello.multilanguage/src/styles.scss new file mode 100644 index 00000000..b48c8df5 --- /dev/null +++ b/samples-angular/hello.multilanguage/src/styles.scss @@ -0,0 +1,4 @@ +@import "@angular/material/prebuilt-themes/indigo-pink.css"; + +html, body { height: 100%; } +body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; } diff --git a/samples-angular/hello.multilanguage/src/test.ts b/samples-angular/hello.multilanguage/src/test.ts new file mode 100644 index 00000000..c04c8760 --- /dev/null +++ b/samples-angular/hello.multilanguage/src/test.ts @@ -0,0 +1,26 @@ +// This file is required by karma.conf.js and loads recursively all the .spec and framework files + +import 'zone.js/testing'; +import { getTestBed } from '@angular/core/testing'; +import { + BrowserDynamicTestingModule, + platformBrowserDynamicTesting +} from '@angular/platform-browser-dynamic/testing'; + +declare const require: { + context(path: string, deep?: boolean, filter?: RegExp): { + (id: string): T; + keys(): string[]; + }; +}; + +// First, initialize the Angular testing environment. +getTestBed().initTestEnvironment( + BrowserDynamicTestingModule, + platformBrowserDynamicTesting(), +); + +// Then we find all the tests. +const context = require.context('./', true, /\.spec\.ts$/); +// And load the modules. +context.keys().forEach(context); diff --git a/samples-angular/hello.multilanguage/tsconfig.app.json b/samples-angular/hello.multilanguage/tsconfig.app.json new file mode 100644 index 00000000..da9cb8b9 --- /dev/null +++ b/samples-angular/hello.multilanguage/tsconfig.app.json @@ -0,0 +1,15 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/app", + "types": [] + }, + "files": [ + "src/main.ts", + "src/polyfills.ts" + ], + "include": [ + "src/**/*.d.ts" + ] +} \ No newline at end of file diff --git a/samples-angular/hello.multilanguage/tsconfig.json b/samples-angular/hello.multilanguage/tsconfig.json new file mode 100644 index 00000000..eaf3a2bc --- /dev/null +++ b/samples-angular/hello.multilanguage/tsconfig.json @@ -0,0 +1,26 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "baseUrl": "./", + "outDir": "./dist/out-tsc", + "sourceMap": true, + "declaration": false, + "downlevelIteration": true, + "experimentalDecorators": true, + "moduleResolution": "node", + "importHelpers": true, + "target": "es2015", + "module": "es2020", + "types": [ + "node" + ], + "lib": [ + "es2018", + "dom" + ] + }, + "angularCompilerOptions": { + "fullTemplateTypeCheck": true, + "strictInjectionParameters": true + } +} diff --git a/samples-angular/hello.multilanguage/tsconfig.spec.json b/samples-angular/hello.multilanguage/tsconfig.spec.json new file mode 100644 index 00000000..87be9d5b --- /dev/null +++ b/samples-angular/hello.multilanguage/tsconfig.spec.json @@ -0,0 +1,18 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/spec", + "types": [ + "jasmine" + ] + }, + "files": [ + "src/test.ts", + "src/polyfills.ts" + ], + "include": [ + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} \ No newline at end of file diff --git a/samples-angular/hello.multilanguage/tslint.json b/samples-angular/hello.multilanguage/tslint.json new file mode 100644 index 00000000..d4ec93fe --- /dev/null +++ b/samples-angular/hello.multilanguage/tslint.json @@ -0,0 +1,148 @@ +{ + "extends": "tslint:recommended", + "rules": { + "align": { + "options": [ + "parameters", + "statements" + ] + }, + "array-type": false, + "arrow-return-shorthand": true, + "curly": true, + "deprecation": { + "severity": "warning" + }, + "component-class-suffix": true, + "contextual-lifecycle": true, + "directive-class-suffix": true, + "directive-selector": [ + true, + "attribute", + "app", + "camelCase" + ], + "component-selector": [ + true, + "element", + "app", + "kebab-case" + ], + "eofline": true, + "import-blacklist": [ + true, + "rxjs/Rx" + ], + "import-spacing": true, + "indent": { + "options": [ + "spaces" + ] + }, + "max-classes-per-file": false, + "max-line-length": [ + true, + 140 + ], + "member-ordering": [ + true, + { + "order": [ + "static-field", + "instance-field", + "static-method", + "instance-method" + ] + } + ], + "no-console": [ + true, + "debug", + "info", + "time", + "timeEnd", + "trace" + ], + "no-empty": false, + "no-inferrable-types": [ + true, + "ignore-params" + ], + "no-non-null-assertion": true, + "no-redundant-jsdoc": true, + "no-switch-case-fall-through": true, + "no-var-requires": false, + "object-literal-key-quotes": [ + true, + "as-needed" + ], + "quotemark": [ + true, + "single" + ], + "semicolon": { + "options": [ + "always" + ] + }, + "space-before-function-paren": { + "options": { + "anonymous": "never", + "asyncArrow": "always", + "constructor": "never", + "method": "never", + "named": "never" + } + }, + "typedef-whitespace": { + "options": [ + { + "call-signature": "nospace", + "index-signature": "nospace", + "parameter": "nospace", + "property-declaration": "nospace", + "variable-declaration": "nospace" + }, + { + "call-signature": "onespace", + "index-signature": "onespace", + "parameter": "onespace", + "property-declaration": "onespace", + "variable-declaration": "onespace" + } + ] + }, + "variable-name": { + "options": [ + "ban-keywords", + "check-format", + "allow-pascal-case" + ] + }, + "whitespace": { + "options": [ + "check-branch", + "check-decl", + "check-operator", + "check-separator", + "check-type", + "check-typecast" + ] + }, + "no-conflicting-lifecycle": true, + "no-host-metadata-property": true, + "no-input-rename": true, + "no-inputs-metadata-property": true, + "no-output-native": true, + "no-output-on-prefix": true, + "no-output-rename": true, + "no-outputs-metadata-property": true, + "template-banana-in-box": true, + "template-no-negated-async": true, + "use-lifecycle-interface": true, + "use-pipe-transform-interface": true + }, + "rulesDirectory": [ + "codelyzer" + ] +} diff --git a/samples-cpp/README.md b/samples-cpp/README.md index 417d0b47..33d93012 100644 --- a/samples-cpp/README.md +++ b/samples-cpp/README.md @@ -5,6 +5,7 @@ * ctrlX AUTOMATION SDK build environment * ctrlX AUTOMATION SDK version * ctrlX COREvirtual or ctrlX CORE + * Visual Studio Code installed on your host computer ## Find out the supported samples diff --git a/samples-cpp/datalayer.client.sub/.vscode/tasks.json b/samples-cpp/datalayer.client.sub/.vscode/tasks.json index 55d35af4..38152944 100644 --- a/samples-cpp/datalayer.client.sub/.vscode/tasks.json +++ b/samples-cpp/datalayer.client.sub/.vscode/tasks.json @@ -4,7 +4,7 @@ "version": "2.0.0", "tasks": [ { - "label": "build snap amd64", + "label": "Build snap amd64", "type": "shell", "command": "bash", "args": [ @@ -13,11 +13,11 @@ "problemMatcher": [], "group": { "kind": "build", - "isDefault": true + "isDefault": false } }, { - "label": "build snap arm64", + "label": "Build snap arm64", "type": "shell", "command": "bash", "args": [ @@ -26,8 +26,179 @@ "problemMatcher": [], "group": { "kind": "build", - "isDefault": true + "isDefault": false } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + ], + "inputs": [ + { + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", + "type": "promptString", + "description": "IP address", + "default": "192.168.1.1" + }, + { + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", + "type": "promptString", + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" + }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" } ] } \ No newline at end of file diff --git a/samples-cpp/datalayer.client/.vscode/tasks.json b/samples-cpp/datalayer.client/.vscode/tasks.json index 55d35af4..38152944 100644 --- a/samples-cpp/datalayer.client/.vscode/tasks.json +++ b/samples-cpp/datalayer.client/.vscode/tasks.json @@ -4,7 +4,7 @@ "version": "2.0.0", "tasks": [ { - "label": "build snap amd64", + "label": "Build snap amd64", "type": "shell", "command": "bash", "args": [ @@ -13,11 +13,11 @@ "problemMatcher": [], "group": { "kind": "build", - "isDefault": true + "isDefault": false } }, { - "label": "build snap arm64", + "label": "Build snap arm64", "type": "shell", "command": "bash", "args": [ @@ -26,8 +26,179 @@ "problemMatcher": [], "group": { "kind": "build", - "isDefault": true + "isDefault": false } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + ], + "inputs": [ + { + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", + "type": "promptString", + "description": "IP address", + "default": "192.168.1.1" + }, + { + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", + "type": "promptString", + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" + }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" } ] } \ No newline at end of file diff --git a/samples-cpp/datalayer.diagnosis/.vscode/tasks.json b/samples-cpp/datalayer.diagnosis/.vscode/tasks.json index 5a955dd9..4c6318d4 100644 --- a/samples-cpp/datalayer.diagnosis/.vscode/tasks.json +++ b/samples-cpp/datalayer.diagnosis/.vscode/tasks.json @@ -4,7 +4,7 @@ "version": "2.0.0", "tasks": [ { - "label": "build snap amd64", + "label": "Build snap amd64", "type": "shell", "command": "bash", "args": [ @@ -13,11 +13,11 @@ "problemMatcher": [], "group": { "kind": "build", - "isDefault": true + "isDefault": false } }, { - "label": "build snap arm64", + "label": "Build snap arm64", "type": "shell", "command": "bash", "args": [ @@ -26,28 +26,185 @@ "problemMatcher": [], "group": { "kind": "build", - "isDefault": true + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false } }, { "label": "Launch Remote GDB Server", "type": "shell", "problemMatcher": "$gcc", - "command": "ssh ${input:Root-User}@${input:Target-IP} \"sudo snap run --experimental-gdbserver=:12345 datalayerdiagnosis.datalayerDiagnosis\" " + "command": "ssh ${input:SSHUser}@${input:IPAddress} \"sudo snap run --experimental-gdbserver=:12345 datalayerdiagnosis.datalayerDiagnosis\" " }, ], "inputs": [ { - "id": "Target-IP", + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", "type": "promptString", - "description": "Insert target ip", + "description": "IP address", "default": "192.168.1.1" }, { - "id": "Root-User", + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", "type": "promptString", - "description": "Insert user", - "default": "rexroot" + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" + } ] } \ No newline at end of file diff --git a/samples-cpp/datalayer.ecat.io/.vscode/tasks.json b/samples-cpp/datalayer.ecat.io/.vscode/tasks.json index 5d707aed..38152944 100644 --- a/samples-cpp/datalayer.ecat.io/.vscode/tasks.json +++ b/samples-cpp/datalayer.ecat.io/.vscode/tasks.json @@ -1,33 +1,204 @@ -{ - // See https://go.microsoft.com/fwlink/?LinkId=733558 - // for the documentation about the tasks.json format - "version": "2.0.0", - "tasks": [ - { - "label": "build snap amd64", - "type": "shell", - "command": "bash", - "args": [ - "build-snap-amd64.sh" - ], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build snap arm64", - "type": "shell", - "command": "bash", - "args": [ - "build-snap-arm64.sh" - ], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - } - ] +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "Build snap amd64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-amd64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build snap arm64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-arm64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + ], + "inputs": [ + { + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", + "type": "promptString", + "description": "IP address", + "default": "192.168.1.1" + }, + { + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", + "type": "promptString", + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" + }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" + } + ] } \ No newline at end of file diff --git a/samples-cpp/datalayer.provider.all-data/.vscode/tasks.json b/samples-cpp/datalayer.provider.all-data/.vscode/tasks.json index d2a018eb..38152944 100644 --- a/samples-cpp/datalayer.provider.all-data/.vscode/tasks.json +++ b/samples-cpp/datalayer.provider.all-data/.vscode/tasks.json @@ -4,7 +4,7 @@ "version": "2.0.0", "tasks": [ { - "label": "build snap amd64", + "label": "Build snap amd64", "type": "shell", "command": "bash", "args": [ @@ -13,11 +13,11 @@ "problemMatcher": [], "group": { "kind": "build", - "isDefault": true + "isDefault": false } }, { - "label": "build snap arm64", + "label": "Build snap arm64", "type": "shell", "command": "bash", "args": [ @@ -26,29 +26,179 @@ "problemMatcher": [], "group": { "kind": "build", - "isDefault": true + "isDefault": false } }, { - "label": "Launch GDB-Server", + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", "type": "shell", - - "problemMatcher": "$gcc", - "command": "ssh ${input:Root-User}@${input:Target-IP} \"sudo snap run --experimental-gdbserver=:12345 alldataprovider.allDataProvider\" ", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } }, ], "inputs": [ { - "id": "Target-IP", + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", "type": "promptString", - "description": "Insert target ip", + "description": "IP address", "default": "192.168.1.1" }, { - "id": "Root-User", + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", "type": "promptString", - "description": "Insert user", - "default": "rexroot" + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" + }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" + } ] } \ No newline at end of file diff --git a/samples-cpp/datalayer.realtime/.vscode/tasks.json b/samples-cpp/datalayer.realtime/.vscode/tasks.json index b4edf0ac..fee057f9 100644 --- a/samples-cpp/datalayer.realtime/.vscode/tasks.json +++ b/samples-cpp/datalayer.realtime/.vscode/tasks.json @@ -4,7 +4,7 @@ "version": "2.0.0", "tasks": [ { - "label": "build snap amd64", + "label": "Build snap amd64", "type": "shell", "command": "bash", "args": [ @@ -13,11 +13,11 @@ "problemMatcher": [], "group": { "kind": "build", - "isDefault": true + "isDefault": false } }, { - "label": "build snap arm64", + "label": "Build snap arm64", "type": "shell", "command": "bash", "args": [ @@ -26,36 +26,191 @@ "problemMatcher": [], "group": { "kind": "build", - "isDefault": true + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false } }, { "label": "Launch GDB-Server Owner", "type": "shell", - "problemMatcher": "$gcc", - "command": "ssh ${input:Root-User}@${input:Target-IP} \"sudo snap run --experimental-gdbserver=:12345 datalayerrealtime.datalayerrealtimeOwner\" ", + "command": "ssh ${input:SSHUser}@${input:IPAddress} \"sudo snap run --experimental-gdbserver=:12345 datalayerrealtime.datalayerrealtimeOwner\" ", }, { "label": "Launch GDB-Server User", "type": "shell", - "problemMatcher": "$gcc", - "command": "ssh ${input:Root-User}@${input:Target-IP} \"sudo snap run --experimental-gdbserver=:12345 datalayerrealtime.datalayerrealtimeUser\" ", + "command": "ssh ${input:SSHUser}@${input:IPAddress} \"sudo snap run --experimental-gdbserver=:12345 datalayerrealtime.datalayerrealtimeUser\" ", }, ], "inputs": [ { - "id": "Target-IP", + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", "type": "promptString", - "description": "Insert target ip", + "description": "IP address", "default": "192.168.1.1" }, { - "id": "Root-User", + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", "type": "promptString", - "description": "Insert user", - "default": "rexroot" + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" + } ] } \ No newline at end of file diff --git a/samples-cpp/datalayer.register.node/.vscode/tasks.json b/samples-cpp/datalayer.register.node/.vscode/tasks.json index 71c7448b..99893f7d 100644 --- a/samples-cpp/datalayer.register.node/.vscode/tasks.json +++ b/samples-cpp/datalayer.register.node/.vscode/tasks.json @@ -4,7 +4,7 @@ "version": "2.0.0", "tasks": [ { - "label": "build snap amd64", + "label": "Build snap amd64", "type": "shell", "command": "bash", "args": [ @@ -13,11 +13,11 @@ "problemMatcher": [], "group": { "kind": "build", - "isDefault": true + "isDefault": false } }, { - "label": "build snap arm64", + "label": "Build snap arm64", "type": "shell", "command": "bash", "args": [ @@ -26,28 +26,185 @@ "problemMatcher": [], "group": { "kind": "build", - "isDefault": true + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false } }, { "label": "Launch Remote GDB Server", "type": "shell", "problemMatcher": "$gcc", - "command": "ssh ${input:Root-User}@${input:Target-IP} \"sudo snap run --experimental-gdbserver=:12345 registernode.registerNode\" ", + "command": "ssh ${input:SSHUser}@${input:IPAddress} \"sudo snap run --experimental-gdbserver=:12345 registernode.registerNode\" ", }, ], "inputs": [ { - "id": "Target-IP", + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", "type": "promptString", - "description": "Insert target ip", + "description": "IP address", "default": "192.168.1.1" }, { - "id": "Root-User", + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", "type": "promptString", - "description": "Insert user", - "default": "rexroot" + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" + } ] } \ No newline at end of file diff --git a/samples-cpp/diagnostics.logbook/.vscode/tasks.json b/samples-cpp/diagnostics.logbook/.vscode/tasks.json index 55d35af4..38152944 100644 --- a/samples-cpp/diagnostics.logbook/.vscode/tasks.json +++ b/samples-cpp/diagnostics.logbook/.vscode/tasks.json @@ -4,7 +4,7 @@ "version": "2.0.0", "tasks": [ { - "label": "build snap amd64", + "label": "Build snap amd64", "type": "shell", "command": "bash", "args": [ @@ -13,11 +13,11 @@ "problemMatcher": [], "group": { "kind": "build", - "isDefault": true + "isDefault": false } }, { - "label": "build snap arm64", + "label": "Build snap arm64", "type": "shell", "command": "bash", "args": [ @@ -26,8 +26,179 @@ "problemMatcher": [], "group": { "kind": "build", - "isDefault": true + "isDefault": false } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + ], + "inputs": [ + { + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", + "type": "promptString", + "description": "IP address", + "default": "192.168.1.1" + }, + { + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", + "type": "promptString", + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" + }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" } ] } \ No newline at end of file diff --git a/samples-cpp/hello.plc/.vscode/tasks.json b/samples-cpp/hello.plc/.vscode/tasks.json index 55d35af4..38152944 100644 --- a/samples-cpp/hello.plc/.vscode/tasks.json +++ b/samples-cpp/hello.plc/.vscode/tasks.json @@ -4,7 +4,7 @@ "version": "2.0.0", "tasks": [ { - "label": "build snap amd64", + "label": "Build snap amd64", "type": "shell", "command": "bash", "args": [ @@ -13,11 +13,11 @@ "problemMatcher": [], "group": { "kind": "build", - "isDefault": true + "isDefault": false } }, { - "label": "build snap arm64", + "label": "Build snap arm64", "type": "shell", "command": "bash", "args": [ @@ -26,8 +26,179 @@ "problemMatcher": [], "group": { "kind": "build", - "isDefault": true + "isDefault": false } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + ], + "inputs": [ + { + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", + "type": "promptString", + "description": "IP address", + "default": "192.168.1.1" + }, + { + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", + "type": "promptString", + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" + }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" } ] } \ No newline at end of file diff --git a/samples-cpp/hello.world/.vscode/tasks.json b/samples-cpp/hello.world/.vscode/tasks.json index 55d35af4..38152944 100644 --- a/samples-cpp/hello.world/.vscode/tasks.json +++ b/samples-cpp/hello.world/.vscode/tasks.json @@ -4,7 +4,7 @@ "version": "2.0.0", "tasks": [ { - "label": "build snap amd64", + "label": "Build snap amd64", "type": "shell", "command": "bash", "args": [ @@ -13,11 +13,11 @@ "problemMatcher": [], "group": { "kind": "build", - "isDefault": true + "isDefault": false } }, { - "label": "build snap arm64", + "label": "Build snap arm64", "type": "shell", "command": "bash", "args": [ @@ -26,8 +26,179 @@ "problemMatcher": [], "group": { "kind": "build", - "isDefault": true + "isDefault": false } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + ], + "inputs": [ + { + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", + "type": "promptString", + "description": "IP address", + "default": "192.168.1.1" + }, + { + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", + "type": "promptString", + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" + }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" } ] } \ No newline at end of file diff --git a/samples-go/README.md b/samples-go/README.md index 8be5596c..ec61fea3 100644 --- a/samples-go/README.md +++ b/samples-go/README.md @@ -2,12 +2,13 @@ ## Find out the supported samples - ### Basic Samples * [ctrlX Data Layer Client](./datalayer.client/README.md) +* [ctrlX Data Layer Client Extensions](./datalayer.client.ext/README.md) * [ctrlX Data Layer Provider](./datalayer.provider/README.md) * [Hello Webserver](./hello.webserver/README.md) +* [WebDAV Client](./webdav.client/README.md) ### Advanced Samples @@ -16,4 +17,4 @@ ## Build a Snap -See [Samples Overview](../samples.md) \ No newline at end of file +See [Samples Overview](../samples.md) diff --git a/samples-go/appdata/.vscode/tasks.json b/samples-go/appdata/.vscode/tasks.json index 7c31f666..38152944 100644 --- a/samples-go/appdata/.vscode/tasks.json +++ b/samples-go/appdata/.vscode/tasks.json @@ -1,33 +1,204 @@ { - // See https://go.microsoft.com/fwlink/?LinkId=733558 - // for the documentation about the tasks.json format - "version": "2.0.0", - "tasks": [ - { - "label": "build snap amd64", - "type": "shell", - "command": "bash", - "args": [ - "build-snap-amd64.sh" - ], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build snap arm64", - "type": "shell", - "command": "bash", - "args": [ - "build-snap-arm64.sh" - ], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - } - ] + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "Build snap amd64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-amd64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build snap arm64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-arm64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + ], + "inputs": [ + { + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", + "type": "promptString", + "description": "IP address", + "default": "192.168.1.1" + }, + { + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", + "type": "promptString", + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" + }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" + } + ] } \ No newline at end of file diff --git a/samples-go/appdata/go.mod b/samples-go/appdata/go.mod index 1480bb6c..4a7fa7ed 100644 --- a/samples-go/appdata/go.mod +++ b/samples-go/appdata/go.mod @@ -1,5 +1,5 @@ module samples-go/appdata -go 1.16 +go 1.19 require github.com/golang-jwt/jwt v3.2.2+incompatible diff --git a/samples-go/datalayer.client.ext/.editorconfig b/samples-go/datalayer.client.ext/.editorconfig new file mode 100644 index 00000000..c1322dc7 --- /dev/null +++ b/samples-go/datalayer.client.ext/.editorconfig @@ -0,0 +1,12 @@ +# EditorConfig is awesome: https://EditorConfig.org + +# top-most EditorConfig file +root = true + +[*] +indent_style = space +indent_size = 4 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = false +insert_final_newline = false \ No newline at end of file diff --git a/samples-go/datalayer.client.ext/.gitignore b/samples-go/datalayer.client.ext/.gitignore new file mode 100644 index 00000000..416488fa --- /dev/null +++ b/samples-go/datalayer.client.ext/.gitignore @@ -0,0 +1 @@ +datalayer.client.ext diff --git a/samples-go/datalayer.client.ext/.vscode/launch.json b/samples-go/datalayer.client.ext/.vscode/launch.json new file mode 100644 index 00000000..994c7d9f --- /dev/null +++ b/samples-go/datalayer.client.ext/.vscode/launch.json @@ -0,0 +1,16 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Launch Package", + "type": "go", + "request": "launch", + "mode": "auto", + "program": "${workspaceFolder}/cmd/datalayer.client.ext/client.go", + "cwd": "${workspaceFolder}" + } + ] +} \ No newline at end of file diff --git a/samples-go/datalayer.client.ext/.vscode/settings.json b/samples-go/datalayer.client.ext/.vscode/settings.json new file mode 100644 index 00000000..a4606455 --- /dev/null +++ b/samples-go/datalayer.client.ext/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "go.inferGopath": false +} \ No newline at end of file diff --git a/samples-go/datalayer.client.ext/.vscode/tasks.json b/samples-go/datalayer.client.ext/.vscode/tasks.json new file mode 100644 index 00000000..38152944 --- /dev/null +++ b/samples-go/datalayer.client.ext/.vscode/tasks.json @@ -0,0 +1,204 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "Build snap amd64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-amd64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build snap arm64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-arm64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + ], + "inputs": [ + { + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", + "type": "promptString", + "description": "IP address", + "default": "192.168.1.1" + }, + { + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", + "type": "promptString", + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" + }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" + } + ] +} \ No newline at end of file diff --git a/samples-go/datalayer.client.ext/README.md b/samples-go/datalayer.client.ext/README.md new file mode 100644 index 00000000..2f6219cf --- /dev/null +++ b/samples-go/datalayer.client.ext/README.md @@ -0,0 +1,59 @@ +# Example ctrlX Data Layer Client Extensions + +## Introduction + +The sample demonstrates how to uses the subcription and bulk from the ctrlX Data Layer. + +## Function Description + +The app connects to the ctrlX Data Layer using either port 8443 or 443. +A subscription is used to get values by data change event in a deterministic publish interval. +The single read is performed every 10 seconds in an endless loop. + +If the Data Layer connection breaks the app will exit. After 10s it will be automatically restarted by snapd. + +## Prerequisites + +See the description on [ctrlX Data Layer client and provider library for golang](https://github.com/boschrexroth/ctrlx-datalayer-golang) + +## Visual Studio Code + +To use Golang within Visual Studio Code, we recommend using the [Go for Visual Studio Code](https://github.com/golang/vscode-go) extension. The corresponding documentation can also be found under this link. + +Open this project folder directly, then the go build environment is set correctly. + +## Building + +Dependency updates with `go mod tidy` + +Build the executable with `go build ./cmd/...` + +Build the snap with `snapcraft --destructive-mode` + +## Runtime + +This application needs "sdk-cpp-alldata" as provider. + +## License + +MIT License + +Copyright (c) 2021-2023 Bosch Rexroth AG + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/samples-go/datalayer.client.ext/build-snap-amd64.sh b/samples-go/datalayer.client.ext/build-snap-amd64.sh new file mode 100644 index 00000000..1a4af218 --- /dev/null +++ b/samples-go/datalayer.client.ext/build-snap-amd64.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +snapcraft clean --destructive-mode +snapcraft --destructive-mode --target-arch=amd64 --enable-experimental-target-arch diff --git a/samples-go/datalayer.client.ext/build-snap-arm64.sh b/samples-go/datalayer.client.ext/build-snap-arm64.sh new file mode 100644 index 00000000..9d6d8e6b --- /dev/null +++ b/samples-go/datalayer.client.ext/build-snap-arm64.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +snapcraft clean --destructive-mode +snapcraft --destructive-mode --target-arch=arm64 --enable-experimental-target-arch diff --git a/samples-go/datalayer.client.ext/go.mod b/samples-go/datalayer.client.ext/go.mod new file mode 100644 index 00000000..ff02d839 --- /dev/null +++ b/samples-go/datalayer.client.ext/go.mod @@ -0,0 +1,7 @@ +module datalayer.client + +go 1.19 + +require github.com/boschrexroth/ctrlx-datalayer-golang v1.2.0 + +require github.com/google/flatbuffers v23.1.21+incompatible // indirect diff --git a/samples-go/datalayer.client.ext/go.sum b/samples-go/datalayer.client.ext/go.sum new file mode 100644 index 00000000..e19fee2f --- /dev/null +++ b/samples-go/datalayer.client.ext/go.sum @@ -0,0 +1,22 @@ +github.com/boschrexroth/ctrlx-datalayer-golang v1.2.0 h1:OGxFO7NbveFyYkq8NY05xQxatjqRSyxiCB9T8P9MBc0= +github.com/boschrexroth/ctrlx-datalayer-golang v1.2.0/go.mod h1:i0ex6o3HhWHDSS0KEmRuHZOk3FVdJamzyk+tp3qmxkg= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/google/flatbuffers v1.12.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/flatbuffers v23.1.21+incompatible h1:bUqzx/MXCDxuS0hRJL2EfjyZL3uQrPbMocUa8zGqsTA= +github.com/google/flatbuffers v23.1.21+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/loov/hrtime v1.0.1/go.mod h1:yDY3Pwv2izeY4sq7YcPX/dtLwzg5NU1AxWuWxKwd0p0= +github.com/loov/hrtime v1.0.3/go.mod h1:yDY3Pwv2izeY4sq7YcPX/dtLwzg5NU1AxWuWxKwd0p0= +github.com/loov/hrtime/hrplot v1.0.2/go.mod h1:9t65xYn4d42ntjv40Wt5lbU72/VC5S0zGDgjC8kD5BU= +github.com/loov/plot v0.0.0-20200413101321-e09a6f01d2f5/go.mod h1:gSrhfSMoiPGG0CZ9E66kXjaHxFw0fzJhooyicOnz5z4= +github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852 h1:Yl0tPBa8QPjGmesFh1D0rDy+q1Twx6FyU7VWHi8wZbI= +github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852/go.mod h1:eqOVx5Vwu4gd2mmMZvVZsgIqNSaW3xxRThUJ0k/TPk4= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/samples-go/datalayer.client.ext/pkg/client/bulk.go b/samples-go/datalayer.client.ext/pkg/client/bulk.go new file mode 100644 index 00000000..c76d0dfa --- /dev/null +++ b/samples-go/datalayer.client.ext/pkg/client/bulk.go @@ -0,0 +1,75 @@ +/** + * MIT License + * + * Copyright (c) 2021-2023 Bosch Rexroth AG + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package client + +import "github.com/boschrexroth/ctrlx-datalayer-golang/pkg/datalayer" + +type bulkClient struct { + client *datalayer.Client +} + +func NewBulkClient(c *datalayer.Client) *bulkClient { + call := &bulkClient{client: c} + return call +} + +func DeleteBulkClient(s *bulkClient) { + if s == nil { + return + } + if s.client == nil { + return + } + s.client = nil +} + +// runs bulk example once +func (b *bulkClient) Run() { + + bulk := b.client.CreateBulk() + defer datalayer.DeleteBulk(bulk) + m := []string{ + "framework/metrics/system/cpu-utilisation-percent", + "framework/metrics/system/memavailable-mb", + } + + args := []datalayer.BulkReadArg{} + for _, value := range m { + arg := datalayer.BulkReadArg{Address: value, Argument: nil} + args = append(args, arg) + } + + r := bulk.Read(args...) + if r != datalayer.ResultOk { + return + } + + for key, value := range m { + println("Addresse: ", value) + println("Result : ", bulk.Response[key].Result) + data := bulk.Response[key].Data + println("Value : ", data.GetFloat64()) + println("Time :", bulk.Response[key].Time.String()) + } +} diff --git a/samples-go/datalayer.client.ext/pkg/client/calldatalayerclient.go b/samples-go/datalayer.client.ext/pkg/client/calldatalayerclient.go new file mode 100644 index 00000000..897e6b42 --- /dev/null +++ b/samples-go/datalayer.client.ext/pkg/client/calldatalayerclient.go @@ -0,0 +1,69 @@ +/** + * MIT License + * + * Copyright (c) 2021-2023 Bosch Rexroth AG + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package client + +import ( + "github.com/boschrexroth/ctrlx-datalayer-golang/pkg/datalayer" +) + +type CallDatalayerClient struct { + client *datalayer.Client + sub *subscriptionClient +} + +func NewCallDatalayerClient(c *datalayer.Client) *CallDatalayerClient { + call := &CallDatalayerClient{client: c} + return call +} + +func DeleteCallDatalayerClient(c *CallDatalayerClient) { + if c == nil { + return + } + if c.client == nil { + return + } + DeleteSubscriptionClient(c.sub) + datalayer.DeleteClient(c.client) + c.sub = nil + c.client = nil +} + +func (c *CallDatalayerClient) Run() { + + c.runBulk() + + c.runSubscription() +} + +func (c *CallDatalayerClient) runBulk() { + b := NewBulkClient(c.client) + defer DeleteBulkClient(b) + b.Run() +} + +func (c *CallDatalayerClient) runSubscription() { + c.sub = NewSubscriptionClient(c.client) + c.sub.Run() +} diff --git a/samples-go/datalayer.client.ext/pkg/client/subscription.go b/samples-go/datalayer.client.ext/pkg/client/subscription.go new file mode 100644 index 00000000..4652228d --- /dev/null +++ b/samples-go/datalayer.client.ext/pkg/client/subscription.go @@ -0,0 +1,93 @@ +/** + * MIT License + * + * Copyright (c) 2021-2023 Bosch Rexroth AG + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package client + +import ( + "fmt" + + "github.com/boschrexroth/ctrlx-datalayer-golang/pkg/datalayer" +) + +type subscriptionClient struct { + client *datalayer.Client + sub *datalayer.Subscription +} + +func NewSubscriptionClient(c *datalayer.Client) *subscriptionClient { + call := &subscriptionClient{client: c} + return call +} + +func DeleteSubscriptionClient(s *subscriptionClient) { + if s == nil { + return + } + if s.client == nil { + return + } + if s.sub != nil { + s.client.DeleteSubscription(s.sub) + } + s.client = nil + s.sub = nil +} + +/* +// global onSubscribe +func onSubscribe(result datalayer.Result, items map[string]datalayer.Variant) { + if result != datalayer.ResultOk { + fmt.Println("onSubscribe result: ", result) + return + } + for k, v := range items { + fmt.Println(k, " ", v.GetUint32()) + } +} +*/ + +// onSubscribe +func (s *subscriptionClient) onSubscribe(result datalayer.Result, items map[string]datalayer.Variant) { + if result != datalayer.ResultOk { + fmt.Println("onSubscribe result: ", result) + return + } + for k, v := range items { + fmt.Println(k, " ", v.GetUint32()) + } +} + +func (s *subscriptionClient) Run() { + + //sub, r := s.client.CreateSubscription("mySub", datalayer.DefaultSubscriptionProperties(), onSubscribe) + sub, r := s.client.CreateSubscription("mySub", datalayer.DefaultSubscriptionProperties(), s.onSubscribe) + if r != datalayer.ResultOk { + fmt.Println("CreateSubscription result: ", r) + return + } + + r = sub.Subscribe("framework/metrics/system/cpu-utilisation-percent", + "framework/metrics/system/memused-percent") + + fmt.Println("Subscribe result: ", r) +} diff --git a/samples-go/datalayer.client.ext/snap/snapcraft.yaml b/samples-go/datalayer.client.ext/snap/snapcraft.yaml new file mode 100644 index 00000000..f9c75348 --- /dev/null +++ b/samples-go/datalayer.client.ext/snap/snapcraft.yaml @@ -0,0 +1,57 @@ +name: sdk-go-client-ext +base: core20 +version: '0.1' +summary: ctrlX Data Layer client sample written in Go +description: | + This sample shows how to uses the subscription and bulk from the ctrlX Data Layer + +grade: stable +confinement: strict + +apps: + client: + command: bin/datalayer.client.ext + plugs: + - network + - datalayer + daemon: simple + restart-condition: always + passthrough: + restart-delay: 10s + +parts: + client: + plugin: go + source: . + build-snaps: ['go/1.19/stable'] + stage-packages: + - libzmq5 + - ctrlx-datalayer + build-packages: + - on amd64: + - libsystemd-dev + - libzmq3-dev + - pkg-config + - on arm64: + - libsystemd-dev:arm64 + - libzmq3-dev:arm64 + #- pkg-config:arm64 + override-build: | + case $SNAPCRAFT_ARCH_TRIPLET in + aarch64-linux-gnu) + export GOARCH=arm64 + export GOARM=7 + export CGO_ENABLED=1 + export CC=aarch64-linux-gnu-gcc + ;; + amd64) + export GOARCH=amd64 + ;; + esac + go build -buildvcs=false -o ../install/bin/ ./... + +plugs: + datalayer: + interface: content + content: datalayer + target: $SNAP_DATA/.datalayer \ No newline at end of file diff --git a/samples-go/datalayer.client/.vscode/tasks.json b/samples-go/datalayer.client/.vscode/tasks.json index 7c31f666..38152944 100644 --- a/samples-go/datalayer.client/.vscode/tasks.json +++ b/samples-go/datalayer.client/.vscode/tasks.json @@ -1,33 +1,204 @@ { - // See https://go.microsoft.com/fwlink/?LinkId=733558 - // for the documentation about the tasks.json format - "version": "2.0.0", - "tasks": [ - { - "label": "build snap amd64", - "type": "shell", - "command": "bash", - "args": [ - "build-snap-amd64.sh" - ], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build snap arm64", - "type": "shell", - "command": "bash", - "args": [ - "build-snap-arm64.sh" - ], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - } - ] + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "Build snap amd64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-amd64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build snap arm64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-arm64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + ], + "inputs": [ + { + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", + "type": "promptString", + "description": "IP address", + "default": "192.168.1.1" + }, + { + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", + "type": "promptString", + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" + }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" + } + ] } \ No newline at end of file diff --git a/samples-go/datalayer.client/README.md b/samples-go/datalayer.client/README.md index 352fdf4c..04e42a05 100644 --- a/samples-go/datalayer.client/README.md +++ b/samples-go/datalayer.client/README.md @@ -30,11 +30,15 @@ Build the executable with `go build ./cmd/...` Build the snap with `snapcraft --destructive-mode` +## Runtime + +This application needs "sdk-cpp-alldata" as provider. + ## License MIT License -Copyright (c) 2021-2022 Bosch Rexroth AG +Copyright (c) 2021-2023 Bosch Rexroth AG Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/samples-go/datalayer.client/cmd/datalayerclient/client.go b/samples-go/datalayer.client/cmd/datalayerclient/client.go index 3fcfb1fe..31efe159 100644 --- a/samples-go/datalayer.client/cmd/datalayerclient/client.go +++ b/samples-go/datalayer.client/cmd/datalayerclient/client.go @@ -1,7 +1,7 @@ /** * MIT License * - * Copyright (c) 2021-2022 Bosch Rexroth AG + * Copyright (c) 2021-2023 Bosch Rexroth AG * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -65,12 +65,13 @@ func main() { for c.IsConnected() { callClient.Run() - time.Sleep(1.0) + time.Sleep(1 * time.Second) } + dlc.DeleteCallDatalayerClient(callClient) + system.Stop(false) fmt.Println("INFO stopping Data Layer system") - } // This is the connection string for TCP in the format: tcp://USER:PASSWORD@IP_ADDRESS:2070?sslport=SSL_PORT diff --git a/samples-go/datalayer.client/go.mod b/samples-go/datalayer.client/go.mod index 1efdd23e..ff02d839 100644 --- a/samples-go/datalayer.client/go.mod +++ b/samples-go/datalayer.client/go.mod @@ -1,5 +1,7 @@ module datalayer.client -go 1.13 +go 1.19 -require github.com/boschrexroth/ctrlx-datalayer-golang v1.0.1 +require github.com/boschrexroth/ctrlx-datalayer-golang v1.2.0 + +require github.com/google/flatbuffers v23.1.21+incompatible // indirect diff --git a/samples-go/datalayer.client/go.sum b/samples-go/datalayer.client/go.sum index 6399acc3..e19fee2f 100644 --- a/samples-go/datalayer.client/go.sum +++ b/samples-go/datalayer.client/go.sum @@ -1,9 +1,10 @@ -github.com/boschrexroth/ctrlx-datalayer-golang v1.0.1 h1:O+r/ka5ga1Gr2NlXYl9H9h8nD84Uusood8AQFfp1jKM= -github.com/boschrexroth/ctrlx-datalayer-golang v1.0.1/go.mod h1:i0ex6o3HhWHDSS0KEmRuHZOk3FVdJamzyk+tp3qmxkg= +github.com/boschrexroth/ctrlx-datalayer-golang v1.2.0 h1:OGxFO7NbveFyYkq8NY05xQxatjqRSyxiCB9T8P9MBc0= +github.com/boschrexroth/ctrlx-datalayer-golang v1.2.0/go.mod h1:i0ex6o3HhWHDSS0KEmRuHZOk3FVdJamzyk+tp3qmxkg= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/google/flatbuffers v1.12.0 h1:/PtAHvnBY4Kqnx/xCQ3OIV9uYcSFGScBsWI3Oogeh6w= github.com/google/flatbuffers v1.12.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/flatbuffers v23.1.21+incompatible h1:bUqzx/MXCDxuS0hRJL2EfjyZL3uQrPbMocUa8zGqsTA= +github.com/google/flatbuffers v23.1.21+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/loov/hrtime v1.0.1/go.mod h1:yDY3Pwv2izeY4sq7YcPX/dtLwzg5NU1AxWuWxKwd0p0= github.com/loov/hrtime v1.0.3/go.mod h1:yDY3Pwv2izeY4sq7YcPX/dtLwzg5NU1AxWuWxKwd0p0= github.com/loov/hrtime/hrplot v1.0.2/go.mod h1:9t65xYn4d42ntjv40Wt5lbU72/VC5S0zGDgjC8kD5BU= diff --git a/samples-go/datalayer.client/pkg/client/calldatalayerclient.go b/samples-go/datalayer.client/pkg/client/calldatalayerclient.go index bae217e4..c1a19f42 100644 --- a/samples-go/datalayer.client/pkg/client/calldatalayerclient.go +++ b/samples-go/datalayer.client/pkg/client/calldatalayerclient.go @@ -1,7 +1,7 @@ /** * MIT License * - * Copyright (c) 2021-2022 Bosch Rexroth AG + * Copyright (c) 2021-2023 Bosch Rexroth AG * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -44,6 +44,17 @@ func NewCallDatalayerClient(c *datalayer.Client) *CallDatalayerClient { return call } +func DeleteCallDatalayerClient(c *CallDatalayerClient) { + if c == nil { + return + } + if c.client == nil { + return + } + datalayer.DeleteClient(c.client) + c.client = nil +} + type callbackvalue struct { res datalayer.Result val *datalayer.Variant diff --git a/samples-go/datalayer.client/snap/snapcraft.yaml b/samples-go/datalayer.client/snap/snapcraft.yaml index 2420cc44..606f1e14 100644 --- a/samples-go/datalayer.client/snap/snapcraft.yaml +++ b/samples-go/datalayer.client/snap/snapcraft.yaml @@ -23,7 +23,7 @@ parts: client: plugin: go source: . - build-snaps: ['go/1.17/stable'] + build-snaps: ['go/1.19/stable'] stage-packages: - libzmq5 - ctrlx-datalayer diff --git a/samples-go/datalayer.provider/.vscode/tasks.json b/samples-go/datalayer.provider/.vscode/tasks.json index 7c31f666..38152944 100644 --- a/samples-go/datalayer.provider/.vscode/tasks.json +++ b/samples-go/datalayer.provider/.vscode/tasks.json @@ -1,33 +1,204 @@ { - // See https://go.microsoft.com/fwlink/?LinkId=733558 - // for the documentation about the tasks.json format - "version": "2.0.0", - "tasks": [ - { - "label": "build snap amd64", - "type": "shell", - "command": "bash", - "args": [ - "build-snap-amd64.sh" - ], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build snap arm64", - "type": "shell", - "command": "bash", - "args": [ - "build-snap-arm64.sh" - ], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - } - ] + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "Build snap amd64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-amd64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build snap arm64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-arm64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + ], + "inputs": [ + { + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", + "type": "promptString", + "description": "IP address", + "default": "192.168.1.1" + }, + { + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", + "type": "promptString", + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" + }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" + } + ] } \ No newline at end of file diff --git a/samples-go/datalayer.provider/go.mod b/samples-go/datalayer.provider/go.mod index f40cae73..6136f944 100644 --- a/samples-go/datalayer.provider/go.mod +++ b/samples-go/datalayer.provider/go.mod @@ -1,16 +1,7 @@ module datalayer.provider -go 1.17 +go 1.19 -require github.com/boschrexroth/ctrlx-datalayer-golang v1.1.0 +require github.com/boschrexroth/ctrlx-datalayer-golang v1.2.0 -require ( - github.com/google/flatbuffers v1.12.0 - github.com/stretchr/testify v1.7.0 -) - -require ( - github.com/davecgh/go-spew v1.1.0 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect -) +require github.com/google/flatbuffers v23.1.21+incompatible diff --git a/samples-go/datalayer.provider/go.sum b/samples-go/datalayer.provider/go.sum index f09e07d0..9e1adde3 100644 --- a/samples-go/datalayer.provider/go.sum +++ b/samples-go/datalayer.provider/go.sum @@ -1,9 +1,11 @@ -github.com/boschrexroth/ctrlx-datalayer-golang v1.1.0 h1:k3wlP2vVEMEeqHFY5RpL2VxZid0DhQVYhuLUsS6iUg8= -github.com/boschrexroth/ctrlx-datalayer-golang v1.1.0/go.mod h1:i0ex6o3HhWHDSS0KEmRuHZOk3FVdJamzyk+tp3qmxkg= +github.com/boschrexroth/ctrlx-datalayer-golang v1.2.0 h1:OGxFO7NbveFyYkq8NY05xQxatjqRSyxiCB9T8P9MBc0= +github.com/boschrexroth/ctrlx-datalayer-golang v1.2.0/go.mod h1:i0ex6o3HhWHDSS0KEmRuHZOk3FVdJamzyk+tp3qmxkg= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/google/flatbuffers v1.12.0 h1:/PtAHvnBY4Kqnx/xCQ3OIV9uYcSFGScBsWI3Oogeh6w= github.com/google/flatbuffers v1.12.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/flatbuffers v23.1.21+incompatible h1:bUqzx/MXCDxuS0hRJL2EfjyZL3uQrPbMocUa8zGqsTA= +github.com/google/flatbuffers v23.1.21+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/loov/hrtime v1.0.1/go.mod h1:yDY3Pwv2izeY4sq7YcPX/dtLwzg5NU1AxWuWxKwd0p0= github.com/loov/hrtime v1.0.3/go.mod h1:yDY3Pwv2izeY4sq7YcPX/dtLwzg5NU1AxWuWxKwd0p0= github.com/loov/hrtime/hrplot v1.0.2/go.mod h1:9t65xYn4d42ntjv40Wt5lbU72/VC5S0zGDgjC8kD5BU= @@ -15,7 +17,6 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= diff --git a/samples-go/datalayer.provider/pkg/node/nodedata.go b/samples-go/datalayer.provider/pkg/node/nodedata.go index a12a5143..efb52782 100644 --- a/samples-go/datalayer.provider/pkg/node/nodedata.go +++ b/samples-go/datalayer.provider/pkg/node/nodedata.go @@ -75,16 +75,27 @@ func StartNodeDataHandler(d NodeDataHandler) { return } select { - case event := <-d.Node().Channels().OnCreate: + case event, ok := <-d.Node().Channels().OnCreate: + if !ok { + return + } fmt.Println("event: oncreate: ", d.Name()) event.Callback(datalayer.Result(0), nil) - case event := <-d.Node().Channels().OnRemove: + case event, ok := <-d.Node().Channels().OnRemove: + if !ok { + return + } + fmt.Println("event: OnRemove: ", d.Name()) event.Callback(datalayer.ResultUnsupported, nil) - case event := <-d.Node().Channels().OnBrowse: + case event, ok := <-d.Node().Channels().OnBrowse: func() { + if !ok { + return + } + newData := datalayer.NewVariant() defer datalayer.DeleteVariant(newData) newData.SetArrayString([]string{}) @@ -92,8 +103,12 @@ func StartNodeDataHandler(d NodeDataHandler) { event.Callback(datalayer.Result(0), newData) }() - case event := <-d.Node().Channels().OnRead: + case event, ok := <-d.Node().Channels().OnRead: func() { + if !ok { + return + } + newData := datalayer.NewVariant() defer datalayer.DeleteVariant(newData) d.Value().Copy(newData) @@ -101,13 +116,21 @@ func StartNodeDataHandler(d NodeDataHandler) { event.Callback(datalayer.Result(0), newData) }() - case event := <-d.Node().Channels().OnWrite: + case event, ok := <-d.Node().Channels().OnWrite: + if !ok { + return + } + event.Data.Copy(d.Value()) fmt.Println("event: OnWrite: ", d.Name()) event.Callback(datalayer.Result(0), event.Data) - case event := <-d.Node().Channels().OnMetadata: + case event, ok := <-d.Node().Channels().OnMetadata: func() { + if !ok { + return + } + fmt.Println("event: OnMetadata: ", d.Name()) r, v := d.OnMetadata() diff --git a/samples-go/datalayer.provider/snap/snapcraft.yaml b/samples-go/datalayer.provider/snap/snapcraft.yaml index 299800ab..034cc978 100644 --- a/samples-go/datalayer.provider/snap/snapcraft.yaml +++ b/samples-go/datalayer.provider/snap/snapcraft.yaml @@ -23,7 +23,7 @@ parts: provider: plugin: go source: . - build-snaps: ['go/1.17/stable'] + build-snaps: ['go/1.19/stable'] stage-packages: - libzmq5 - ctrlx-datalayer diff --git a/samples-go/hello.webserver/.vscode/tasks.json b/samples-go/hello.webserver/.vscode/tasks.json index 181f5e3e..38152944 100644 --- a/samples-go/hello.webserver/.vscode/tasks.json +++ b/samples-go/hello.webserver/.vscode/tasks.json @@ -1,29 +1,204 @@ { - // See https://go.microsoft.com/fwlink/?LinkId=733558 - // for the documentation about the tasks.json format - "version": "2.0.0", - "tasks": [ - { - "label": "Snapcraft", - "group": { - "kind": "build", - "isDefault": true - }, - "type": "shell", - "command": "snapcraft --enable-experimental-target-arch --target-arch='${input:arch}' --destructive-mode;snapcraft clean --destructive-mode" - } - - ], - "inputs": [ - { - "id": "arch", - "type":"pickString", - "description": "Architecture", - "options": [ - "amd64", - "arm64" - ], - "default": "amd64" - } - ] + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "Build snap amd64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-amd64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build snap arm64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-arm64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + ], + "inputs": [ + { + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", + "type": "promptString", + "description": "IP address", + "default": "192.168.1.1" + }, + { + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", + "type": "promptString", + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" + }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" + } + ] } \ No newline at end of file diff --git a/samples-go/hello.webserver/README.md b/samples-go/hello.webserver/README.md index 1513acb3..2f4120d4 100644 --- a/samples-go/hello.webserver/README.md +++ b/samples-go/hello.webserver/README.md @@ -2,8 +2,7 @@ The sample __hello-webserver__ contains simple webserver. -## Indroduction - +## Introduction ## Pre-requisites diff --git a/samples-go/hello.webserver/go.mod b/samples-go/hello.webserver/go.mod index 9b13777e..25957f4b 100644 --- a/samples-go/hello.webserver/go.mod +++ b/samples-go/hello.webserver/go.mod @@ -1,4 +1,4 @@ module samples-go/hello.webserver -go 1.16 +go 1.19 diff --git a/samples-go/tpm2.srk/go.mod b/samples-go/tpm2.srk/go.mod index 11dd380b..50711c31 100644 --- a/samples-go/tpm2.srk/go.mod +++ b/samples-go/tpm2.srk/go.mod @@ -1,6 +1,6 @@ module tpm2.srk -go 1.13 +go 1.19 require ( github.com/google/go-tpm v0.3.2 diff --git a/samples-go/webdav.client/.vscode/launch.json b/samples-go/webdav.client/.vscode/launch.json new file mode 100644 index 00000000..608d3c69 --- /dev/null +++ b/samples-go/webdav.client/.vscode/launch.json @@ -0,0 +1,15 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Launch Package", + "type": "go", + "request": "launch", + "mode": "auto", + "program": "${fileDirname}" + } + ] +} \ No newline at end of file diff --git a/samples-go/webdav.client/README.md b/samples-go/webdav.client/README.md new file mode 100644 index 00000000..dae931d7 --- /dev/null +++ b/samples-go/webdav.client/README.md @@ -0,0 +1,45 @@ +# Example WebDAV Client + +## Introduction + +The sample demonstrates how to access to configuration files of a ctrlX device remotely using the WebDAV protocol. + +## Function Description + +The application creates a webdav client and connects to a virtual control (localhost:8443) with the default credentials. +It executes some file operations on the ctrlX-filesystem. + +## Visual Studio Code + +To use Golang within Visual Studio Code, we recommend using the [Go for Visual Studio Code](https://github.com/golang/vscode-go) extension. The corresponding documentation can also be found under this link. + +Open this project folder directly, then the go build environment is set correctly. + +## Building + +Dependency updates with `go mod tidy` +Build the executable with `go build ./cmd/...` + +## License + +MIT License + +Copyright (c) 2021-2022 Bosch Rexroth AG + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/samples-go/webdav.client/cmd/client/main.go b/samples-go/webdav.client/cmd/client/main.go new file mode 100644 index 00000000..daa4ce03 --- /dev/null +++ b/samples-go/webdav.client/cmd/client/main.go @@ -0,0 +1,79 @@ +package main + +import ( + "crypto/tls" + "fmt" + "net/http" + + "github.com/dustin/go-humanize" + "github.com/emersion/go-webdav" +) + +const ( + prefix string = "/solutions/webdav/" +) + +var ( + host string = "https://localhost:8443" + user string = "boschrexroth" // The user needs manage configurations to access the files + password string = "boschrexroth" +) + +func main() { + httpClient := webdav.HTTPClientWithBasicAuth(&http.Client{ + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{ + InsecureSkipVerify: true, + }, + }, + }, user, password) + client, err := webdav.NewClient(httpClient, host+prefix) + if err != nil { + panic(err) + } + + // list the files of the active configuration + printDir(client, "./appdata") + + // remove archive webdav.client + err = client.RemoveAll("./webdav.client") + if err != nil { + fmt.Println(err) + } + + // create archive webdav.client + err = client.Mkdir("./webdav.client") + if err != nil { + fmt.Println(err) + } + + // create a text file + w, err := client.Create("./webdav.client/hello.txt") + if err != nil { + panic(err) + } + _, _ = w.Write([]byte(` + I was here! + Best regards + webdav.client + `)) + _ = w.Close() + printDir(client, "./webdav.client") + + // create a copy of appdata folder + err = client.CopyAll("./appdata", "webdav.client.copy", true) + if err != nil { + fmt.Println(err) + } + printDir(client, "./webdav.client.copy") +} + +func printDir(client *webdav.Client, path string) { + fInfos, err := client.Readdir(path, true) + if err != nil { + panic(err) + } + for _, info := range fInfos { + fmt.Printf("%s\t%s\t%s\n", info.ModTime, humanize.Bytes(uint64(info.Size)), info.Path) + } +} diff --git a/samples-go/webdav.client/go.mod b/samples-go/webdav.client/go.mod new file mode 100644 index 00000000..3f1a50ff --- /dev/null +++ b/samples-go/webdav.client/go.mod @@ -0,0 +1,8 @@ +module github.com/boschrexroth/ctrlx-automation-sdk/samples-go/webdav.client + +go 1.18 + +require ( + github.com/dustin/go-humanize v1.0.1 + github.com/emersion/go-webdav v0.4.0 +) diff --git a/samples-go/webdav.client/go.sum b/samples-go/webdav.client/go.sum new file mode 100644 index 00000000..8c065193 --- /dev/null +++ b/samples-go/webdav.client/go.sum @@ -0,0 +1,7 @@ +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/emersion/go-ical v0.0.0-20220601085725-0864dccc089f/go.mod h1:2MKFUgfNMULRxqZkadG1Vh44we3y5gJAtTBlVsx1BKQ= +github.com/emersion/go-vcard v0.0.0-20191221110513-5f81fa0d3cc7/go.mod h1:HMJKR5wlh/ziNp+sHEDV2ltblO4JD2+IdDOWtGcQBTM= +github.com/emersion/go-webdav v0.4.0 h1:iIkgitJBUNu2c1vL0KqqRb5jDjs38bzM/H7WxewrIh4= +github.com/emersion/go-webdav v0.4.0/go.mod h1:lkPYZO/vsDNV9GPyVMBBsAUZzzxINL97bEVFykApo58= +github.com/teambition/rrule-go v1.7.2/go.mod h1:mBJ1Ht5uboJ6jexKdNUJg2NcwP8uUMNvStWXlJD3MvU= diff --git a/samples-net/.vscode/tasks.json b/samples-net/.vscode/tasks.json index 7161b9aa..669369f8 100644 --- a/samples-net/.vscode/tasks.json +++ b/samples-net/.vscode/tasks.json @@ -1,4 +1,6 @@ { + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format "version": "2.0.0", "tasks": [ { diff --git a/samples-net/appdata/.vscode/tasks.json b/samples-net/appdata/.vscode/tasks.json index f7942623..732c3c25 100644 --- a/samples-net/appdata/.vscode/tasks.json +++ b/samples-net/appdata/.vscode/tasks.json @@ -1,55 +1,228 @@ { - "version": "2.0.0", - "tasks": [ - { - "label": "build snap amd64", - "type": "shell", - "command": "bash", - "args": [ - "build-snap-amd64.sh" - ], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build snap arm64", - "type": "shell", - "command": "bash", - "args": [ - "build-snap-arm64.sh" - ], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build project", - "command": "dotnet", - "type": "process", - "args": [ - "build", - "${workspaceFolder}/appdata.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary" - ], - "problemMatcher": "$msCompile" - }, - { - "label": "clean project", - "command": "dotnet", - "type": "process", - "args": [ - "clean", - "${workspaceFolder}/appdata.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary" - ], - "problemMatcher": "$msCompile" - } - ] + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "build project", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/appdata.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "clean project", + "command": "dotnet", + "type": "process", + "args": [ + "clean", + "${workspaceFolder}/appdata.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "Build snap amd64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-amd64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build snap arm64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-arm64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + ], + "inputs": [ + { + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", + "type": "promptString", + "description": "IP address", + "default": "192.168.1.1" + }, + { + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", + "type": "promptString", + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" + }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" + } + ] } \ No newline at end of file diff --git a/samples-net/appdata/MyApplication.cs b/samples-net/appdata/MyApplication.cs index f114b672..48af3809 100644 --- a/samples-net/appdata/MyApplication.cs +++ b/samples-net/appdata/MyApplication.cs @@ -1,7 +1,7 @@ -/* +/* MIT License -Copyright (c) 2021-2022 Bosch Rexroth AG +Copyright (c) 2021-2023 Bosch Rexroth AG Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -54,11 +54,11 @@ internal class MyApplication private static readonly string HttpApiRouteSave = $"http://localhost:{HttpPort}/ctrlx-dotnet-appdata/api/v1/save"; /// The name of the storage file - private static readonly string StorageFileName = "appdata.json"; + private const string StorageFileName = "appdata.json"; /// The name of the application storage folder /// MUST be same as specified in your *.package-manifest.json file - private static readonly string StorageFolderName = "appdatasample"; + private const string StorageFolderName = "appdatasample"; //Fields private HttpListener _httpListener; @@ -208,7 +208,7 @@ private DLR_RESULT Load() Console.WriteLine($"Loaded application data from file '{path}'."); return DLR_RESULT.DL_OK; } - catch (Exception exc) + catch (Exception exc) when (exc is IOException || exc is JsonException) { Console.WriteLine($"Loading application data from file '{path}' failed! {exc.Message}"); return DLR_RESULT.DL_FAILED; @@ -242,7 +242,7 @@ private DLR_RESULT Save() Console.WriteLine($"Saved application data to file '{path}'."); return DLR_RESULT.DL_OK; } - catch (Exception exc) + catch (IOException exc) { Console.WriteLine($"Saving application data to file '{path}' failed! {exc.Message}"); return DLR_RESULT.DL_FAILED; @@ -264,7 +264,7 @@ private static DLR_RESULT EnsureStorageLocation() Directory.CreateDirectory(path); Console.WriteLine($"Created storage location: '{path}'."); } - catch (Exception exc) + catch (IOException exc) { Console.WriteLine($"Creating storage location '{path}' failed! {exc.Message}"); return DLR_RESULT.DL_FAILED; @@ -282,7 +282,6 @@ private static bool IsAuthorized(JsonWebToken jwt) { //Extract the scopes var scopes = jwt.GetPayloadValue("scope"); - //Console.WriteLine($"scopes: {string.Join(" ", scopes)}"); //Check permissions foreach (var scope in scopes) @@ -367,14 +366,14 @@ private DLR_RESULT StartListenHttp() Console.WriteLine($"Listening to HTTP: {string.Join(", ", _httpListener.Prefixes.ToArray())}"); //Listen - var task = Task.Factory.StartNew(() => + Task.Factory.StartNew(() => { while (true) { // Note: The GetContext method blocks while waiting for a request. - HttpListenerContext context = _httpListener.GetContext(); - HttpListenerRequest request = context.Request; - HttpListenerResponse response = context.Response; + var context = _httpListener.GetContext(); + var request = context.Request; + var response = context.Response; //We received a new app data REST command Console.WriteLine($"Request: {request.Url}"); @@ -420,7 +419,7 @@ private DLR_RESULT StartListenHttp() // Phases we don't care about in this sample can be implemented on demand. // query: Check if loading is possible in the current system statecase "query": - // Hint: The phase 'query' is called 2 times: the first call asks for a setup mode change acknowledge and the second is called during normal load sequence + // Hint: The phase 'query' is called 2 times: the first call asks for a setup mode change acknowledge and the second is called during normal load sequence case "query": // prepare: Perform any required preparatory steps case "prepare": @@ -465,20 +464,19 @@ private DLR_RESULT StartListenHttp() } } } - catch (NotSupportedException exc) + catch (JsonException exc) { //IMPORTANT: //We have to handle _ALL_ possible exceptions here and _ALLWAYS_ return a response! Console.WriteLine($"Failed to parse appdata request! {exc.Message}"); response.StatusCode = (int)HttpStatusCode.InternalServerError; } - response.Close(); } }); return DLR_RESULT.DL_OK; } - catch (Exception exc) + catch (HttpListenerException exc) { Console.WriteLine($"Listening to HTTP failed! {exc.Message}"); return DLR_RESULT.DL_FAILED; diff --git a/samples-net/appdata/Program.cs b/samples-net/appdata/Program.cs index 17085942..ce3ea402 100644 --- a/samples-net/appdata/Program.cs +++ b/samples-net/appdata/Program.cs @@ -1,7 +1,7 @@ /* MIT License -Copyright (c) 2021-2022 Bosch Rexroth AG +Copyright (c) 2021-2023 Bosch Rexroth AG Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/samples-net/appdata/appdata.csproj b/samples-net/appdata/appdata.csproj index ad01a62e..8a53aebb 100644 --- a/samples-net/appdata/appdata.csproj +++ b/samples-net/appdata/appdata.csproj @@ -14,8 +14,8 @@ - - + + \ No newline at end of file diff --git a/samples-net/datalayer.client.browse/.vscode/tasks.json b/samples-net/datalayer.client.browse/.vscode/tasks.json index 3f7081f2..cea2f670 100644 --- a/samples-net/datalayer.client.browse/.vscode/tasks.json +++ b/samples-net/datalayer.client.browse/.vscode/tasks.json @@ -1,55 +1,228 @@ { - "version": "2.0.0", - "tasks": [ - { - "label": "build snap amd64", - "type": "shell", - "command": "bash", - "args": [ - "build-snap-amd64.sh" - ], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build snap arm64", - "type": "shell", - "command": "bash", - "args": [ - "build-snap-arm64.sh" - ], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build project", - "command": "dotnet", - "type": "process", - "args": [ - "build", - "${workspaceFolder}/datalayer.client.browse.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary" - ], - "problemMatcher": "$msCompile" - }, - { - "label": "clean project", - "command": "dotnet", - "type": "process", - "args": [ - "clean", - "${workspaceFolder}/datalayer.client.browse.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary" - ], - "problemMatcher": "$msCompile" - } - ] + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "build project", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/datalayer.client.browse.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "clean project", + "command": "dotnet", + "type": "process", + "args": [ + "clean", + "${workspaceFolder}/datalayer.client.browse.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "Build snap amd64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-amd64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build snap arm64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-arm64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + ], + "inputs": [ + { + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", + "type": "promptString", + "description": "IP address", + "default": "192.168.1.1" + }, + { + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", + "type": "promptString", + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" + }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" + } + ] } \ No newline at end of file diff --git a/samples-net/datalayer.client.browse/ClientExtensions.cs b/samples-net/datalayer.client.browse/ClientExtensions.cs index 78eb0144..36218ea3 100644 --- a/samples-net/datalayer.client.browse/ClientExtensions.cs +++ b/samples-net/datalayer.client.browse/ClientExtensions.cs @@ -1,7 +1,7 @@ -/* +/* MIT License -Copyright (c) 2021-2022 Bosch Rexroth AG +Copyright (c) 2021-2023 Bosch Rexroth AG Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -36,7 +36,7 @@ internal static class ClientExtensions /// /// Defines the MaxChars. /// - private static readonly int MaxChars = 100; + private const int MaxChars = 100; /// /// Browses all nodes in DataLayer tree. @@ -83,9 +83,15 @@ private static void Traverse(this IClient client, Console.WriteLine(valueAsString); var (result, childrenVariant) = client.Browse(address); - if (result != DLR_RESULT.DL_OK) return; + if (result != DLR_RESULT.DL_OK) + { + return; + } var children = childrenVariant.ToStringArray(); - if (children == null) return; + if (children == null) + { + return; + }; for (var i = 0; i < children.Length; i++) { diff --git a/samples-net/datalayer.client.browse/Program.cs b/samples-net/datalayer.client.browse/Program.cs index d8963cfb..d367beda 100644 --- a/samples-net/datalayer.client.browse/Program.cs +++ b/samples-net/datalayer.client.browse/Program.cs @@ -1,7 +1,7 @@ /* MIT License -Copyright (c) 2021-2022 Bosch Rexroth AG +Copyright (c) 2021-2023 Bosch Rexroth AG Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -42,11 +42,11 @@ static void Main(string[] args) system.Start(startBroker: false); Console.WriteLine("ctrlX Data Layer system started."); - // Create a connection string with the parameters according to your environment (see Remote class) - var connectionString = new Remote(ip: "192.168.1.1", sslPort: 443).ToString(); + // Create a remote address with the parameters according to your environment + var remote = new Remote(ip: "192.168.1.1", sslPort: 443).ToString(); // Create the client with remote connection string - using var client = system.Factory.CreateClient(connectionString); + using var client = system.Factory.CreateClient(remote); Console.WriteLine("ctrlX Data Layer client created."); // Check if client is connected diff --git a/samples-net/datalayer.client.browse/Properties/launchSettings.json b/samples-net/datalayer.client.browse/Properties/launchSettings.json new file mode 100644 index 00000000..d20a3ba1 --- /dev/null +++ b/samples-net/datalayer.client.browse/Properties/launchSettings.json @@ -0,0 +1,8 @@ +{ + "profiles": { + "datalayer.client.browse": { + "commandName": "Project", + "nativeDebugging": false + } + } +} \ No newline at end of file diff --git a/samples-net/datalayer.client.browse/datalayer.client.browse.csproj b/samples-net/datalayer.client.browse/datalayer.client.browse.csproj index 541fb1e7..d4367661 100644 --- a/samples-net/datalayer.client.browse/datalayer.client.browse.csproj +++ b/samples-net/datalayer.client.browse/datalayer.client.browse.csproj @@ -8,10 +8,8 @@ - - - - + + diff --git a/samples-net/datalayer.client.bulkread/.vscode/launch.json b/samples-net/datalayer.client.bulkread/.vscode/launch.json index 0f7e60a4..411c0831 100644 --- a/samples-net/datalayer.client.bulkread/.vscode/launch.json +++ b/samples-net/datalayer.client.bulkread/.vscode/launch.json @@ -10,7 +10,7 @@ "request": "launch", "preLaunchTask": "build project", // If you have changed target frameworks, make sure to update the program path. - "program": "${workspaceFolder}/bin/Debug/net6.0/datalayer.client.dll", + "program": "${workspaceFolder}/bin/Debug/net6.0/datalayer.client.bulkread.dll", "args": [], "cwd": "${workspaceFolder}", // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console diff --git a/samples-net/datalayer.client.bulkread/.vscode/tasks.json b/samples-net/datalayer.client.bulkread/.vscode/tasks.json index 9a2a43da..a4bb740f 100644 --- a/samples-net/datalayer.client.bulkread/.vscode/tasks.json +++ b/samples-net/datalayer.client.bulkread/.vscode/tasks.json @@ -1,8 +1,34 @@ { + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format "version": "2.0.0", "tasks": [ { - "label": "build snap amd64", + "label": "build project", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/datalayer.client.bulkread.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "clean project", + "command": "dotnet", + "type": "process", + "args": [ + "clean", + "${workspaceFolder}/datalayer.client.bulkread.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "Build snap amd64", "type": "shell", "command": "bash", "args": [ @@ -11,11 +37,11 @@ "problemMatcher": [], "group": { "kind": "build", - "isDefault": true + "isDefault": false } }, { - "label": "build snap arm64", + "label": "Build snap arm64", "type": "shell", "command": "bash", "args": [ @@ -24,32 +50,179 @@ "problemMatcher": [], "group": { "kind": "build", - "isDefault": true + "isDefault": false } }, { - "label": "build project", - "command": "dotnet", - "type": "process", + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", "args": [ - "build", - "${workspaceFolder}/datalayer.client.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary" + "-ctrlx-virt-NA" ], - "problemMatcher": "$msCompile" + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } }, { - "label": "clean project", - "command": "dotnet", - "type": "process", + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", "args": [ - "clean", - "${workspaceFolder}/datalayer.client.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary" + "-ctrlx-virt-PF" ], - "problemMatcher": "$msCompile" + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + ], + "inputs": [ + { + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", + "type": "promptString", + "description": "IP address", + "default": "192.168.1.1" + }, + { + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", + "type": "promptString", + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" + }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" } ] } \ No newline at end of file diff --git a/samples-net/datalayer.client.bulkread/Program.cs b/samples-net/datalayer.client.bulkread/Program.cs index 8f4d804b..52325f34 100644 --- a/samples-net/datalayer.client.bulkread/Program.cs +++ b/samples-net/datalayer.client.bulkread/Program.cs @@ -1,7 +1,7 @@ /* MIT License -Copyright (c) 2021-2022 Bosch Rexroth AG +Copyright (c) 2021-2023 Bosch Rexroth AG Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -22,10 +22,8 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -using comm.datalayer; using Datalayer; using System; -using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; @@ -44,15 +42,14 @@ static async Task Main(string[] args) // Starts the ctrlX Data Layer system without a new broker (startBroker = false) because one broker is already running on ctrlX device system.Start(startBroker: false); - - + Console.WriteLine("ctrlX Data Layer system started."); - // Create a connection string with the parameters according to your environment (see Remote class) - var connectionString = new Remote(ip: "192.168.1.1", sslPort: 443).ToString(); + // Create a remote address with the parameters according to your environment + var remote = new Remote(ip: "192.168.1.1", sslPort: 443).ToString(); // Create the client with remote connection string - using var client = system.Factory.CreateClient(connectionString); + using var client = system.Factory.CreateClient(remote); Console.WriteLine("ctrlX Data Layer client created."); // Check if client is connected @@ -62,7 +59,7 @@ static async Task Main(string[] args) Console.WriteLine($"Client is not connected -> exit"); return; } - + // Just keep the process running while (true) { @@ -79,19 +76,19 @@ static async Task Main(string[] args) "framework/metrics/system/memused-percent" }; - Console.WriteLine("# client.BulkRead"); - var (result, items) = client.BulkRead(addresses); + Console.WriteLine("BulkRead"); + var (result, items) = client.BulkRead(addresses); if (result.IsGood()) { - - foreach (var item in items) { - Console.WriteLine($"address: {item.Address}, value: {item.Value.ToFloat()}, timestamp: {item.Timestamp}, result: {item.Result}"); + foreach (var item in items) + { + Console.WriteLine($"address: {item.Address}, value: {item.Value.ToFloat()}, timestamp: {item.Timestamp}, result: {item.Result}"); } } //We're using the async bulk read method just for demonstration here. //Hint: If you're not using any async calls, you can remove async keyword from the Main() method signature. - Console.WriteLine("# client.BulkReadAsync"); + Console.WriteLine("BulkReadAsync"); var task = client.BulkReadAsync(addresses); var taskResult = await task; diff --git a/samples-net/datalayer.client.bulkread/Properties/launchSettings.json b/samples-net/datalayer.client.bulkread/Properties/launchSettings.json index 4ff2a9bc..6658ff29 100644 --- a/samples-net/datalayer.client.bulkread/Properties/launchSettings.json +++ b/samples-net/datalayer.client.bulkread/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "datalayer.client.bulkread": { "commandName": "Project", - "nativeDebugging": true + "nativeDebugging": false } } } \ No newline at end of file diff --git a/samples-net/datalayer.client.bulkread/datalayer.client.bulkread.csproj b/samples-net/datalayer.client.bulkread/datalayer.client.bulkread.csproj index a7fa570d..21380eb6 100644 --- a/samples-net/datalayer.client.bulkread/datalayer.client.bulkread.csproj +++ b/samples-net/datalayer.client.bulkread/datalayer.client.bulkread.csproj @@ -8,10 +8,8 @@ - - - - + + diff --git a/samples-net/datalayer.client/.vscode/tasks.json b/samples-net/datalayer.client/.vscode/tasks.json index 9a2a43da..3e9a4819 100644 --- a/samples-net/datalayer.client/.vscode/tasks.json +++ b/samples-net/datalayer.client/.vscode/tasks.json @@ -1,55 +1,228 @@ { - "version": "2.0.0", - "tasks": [ - { - "label": "build snap amd64", - "type": "shell", - "command": "bash", - "args": [ - "build-snap-amd64.sh" - ], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build snap arm64", - "type": "shell", - "command": "bash", - "args": [ - "build-snap-arm64.sh" - ], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build project", - "command": "dotnet", - "type": "process", - "args": [ - "build", - "${workspaceFolder}/datalayer.client.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary" - ], - "problemMatcher": "$msCompile" - }, - { - "label": "clean project", - "command": "dotnet", - "type": "process", - "args": [ - "clean", - "${workspaceFolder}/datalayer.client.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary" - ], - "problemMatcher": "$msCompile" - } - ] + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "build project", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/datalayer.client.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "clean project", + "command": "dotnet", + "type": "process", + "args": [ + "clean", + "${workspaceFolder}/datalayer.client.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "build snap amd64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-amd64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "build snap arm64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-arm64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + ], + "inputs": [ + { + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", + "type": "promptString", + "description": "IP address", + "default": "192.168.1.1" + }, + { + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", + "type": "promptString", + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" + }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" + } + ] } \ No newline at end of file diff --git a/samples-net/datalayer.client/Program.cs b/samples-net/datalayer.client/Program.cs index aece5046..b7852d90 100644 --- a/samples-net/datalayer.client/Program.cs +++ b/samples-net/datalayer.client/Program.cs @@ -1,7 +1,7 @@ /* MIT License -Copyright (c) 2021-2022 Bosch Rexroth AG +Copyright (c) 2021-2023 Bosch Rexroth AG Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -45,11 +45,11 @@ static async Task Main(string[] args) system.Start(startBroker: false); Console.WriteLine("ctrlX Data Layer system started."); - // Create a connection string with the parameters according to your environment (see Remote class) - var connectionString = new Remote(ip: "192.168.1.1", sslPort: 443).ToString(); + // Create a remote address with the parameters according to your environment + var remote = new Remote(ip: "192.168.1.1", sslPort: 443).ToString(); // Create the client with remote connection string - using var client = system.Factory.CreateClient(connectionString); + using var client = system.Factory.CreateClient(remote); Console.WriteLine("ctrlX Data Layer client created."); // Check if client is connected @@ -67,7 +67,6 @@ static async Task Main(string[] args) .SetErrorIntervalMillis(1000) .Build(); - // Define the subscription properties by using Flatbuffers class SubscriptionProperties. // var builder = new FlatBufferBuilder(Variant.DefaultFlatbuffersInitialSize); // var properties = SubscriptionProperties.CreateSubscriptionProperties( diff --git a/samples-net/datalayer.client/Properties/launchSettings.json b/samples-net/datalayer.client/Properties/launchSettings.json new file mode 100644 index 00000000..b051e784 --- /dev/null +++ b/samples-net/datalayer.client/Properties/launchSettings.json @@ -0,0 +1,8 @@ +{ + "profiles": { + "datalayer.client": { + "commandName": "Project", + "nativeDebugging": false + } + } +} \ No newline at end of file diff --git a/samples-net/datalayer.client/datalayer.client.csproj b/samples-net/datalayer.client/datalayer.client.csproj index a7fa570d..21380eb6 100644 --- a/samples-net/datalayer.client/datalayer.client.csproj +++ b/samples-net/datalayer.client/datalayer.client.csproj @@ -8,10 +8,8 @@ - - - - + + diff --git a/samples-net/datalayer.mqtt/.vscode/tasks.json b/samples-net/datalayer.mqtt/.vscode/tasks.json index 867627ec..4fdc1ad8 100644 --- a/samples-net/datalayer.mqtt/.vscode/tasks.json +++ b/samples-net/datalayer.mqtt/.vscode/tasks.json @@ -1,55 +1,228 @@ { - "version": "2.0.0", - "tasks": [ - { - "label": "build snap amd64", - "type": "shell", - "command": "bash", - "args": [ - "build-snap-amd64.sh" - ], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build snap arm64", - "type": "shell", - "command": "bash", - "args": [ - "build-snap-arm64.sh" - ], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build project", - "command": "dotnet", - "type": "process", - "args": [ - "build", - "${workspaceFolder}/datalayer.mqtt.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary" - ], - "problemMatcher": "$msCompile" - }, - { - "label": "clean project", - "command": "dotnet", - "type": "process", - "args": [ - "clean", - "${workspaceFolder}/datalayer.mqtt.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary" - ], - "problemMatcher": "$msCompile" - } - ] + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "build project", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/datalayer.mqtt.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "clean project", + "command": "dotnet", + "type": "process", + "args": [ + "clean", + "${workspaceFolder}/datalayer.mqtt.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "Build snap amd64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-amd64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build snap arm64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-arm64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + ], + "inputs": [ + { + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", + "type": "promptString", + "description": "IP address", + "default": "192.168.1.1" + }, + { + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", + "type": "promptString", + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" + }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" + } + ] } \ No newline at end of file diff --git a/samples-net/datalayer.mqtt/Base/MqttBaseNodeHandler.cs b/samples-net/datalayer.mqtt/Base/MqttBaseNodeHandler.cs index 34d40340..a4a5c5d5 100644 --- a/samples-net/datalayer.mqtt/Base/MqttBaseNodeHandler.cs +++ b/samples-net/datalayer.mqtt/Base/MqttBaseNodeHandler.cs @@ -24,7 +24,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE using comm.datalayer; using Datalayer; -using FlatBuffers; +using Google.FlatBuffers; using System; using System.Collections.Generic; using System.Text; diff --git a/samples-net/datalayer.mqtt/Base/MqttRootNodeHandler.cs b/samples-net/datalayer.mqtt/Base/MqttRootNodeHandler.cs index c1eeeae4..c15fda8c 100644 --- a/samples-net/datalayer.mqtt/Base/MqttRootNodeHandler.cs +++ b/samples-net/datalayer.mqtt/Base/MqttRootNodeHandler.cs @@ -1,7 +1,7 @@ -/* +/* MIT License -Copyright (c) 2021-2022 Bosch Rexroth AG +Copyright (c) 2021-2023 Bosch Rexroth AG Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -38,17 +38,20 @@ namespace Samples.Datalayer.MQTT.Base /// internal class MqttRootNodeHandler : MqttBaseNodeHandler { - /// - /// Creates a handler + /// Creates a handler /// + /// + /// + /// /// /// - public MqttRootNodeHandler(IClient client, IProvider provider, string baseAddress, string name) : + public MqttRootNodeHandler(IClient client, IProvider provider, string brokerAddress, string baseAddress, string name) : base(baseAddress, name) { Client = client; Provider = provider; + MqttClient = new MqttClientWrapper() { BrokerAddress = brokerAddress }; } #region Properties @@ -71,7 +74,7 @@ public MqttRootNodeHandler(IClient client, IProvider provider, string baseAddres /// /// Gets the MQTT client /// - public MqttClientWrapper MqttClient { get; } = new MqttClientWrapper(); + public MqttClientWrapper MqttClient { get; private set; } /// /// Gets the Test Handler @@ -88,7 +91,6 @@ public MqttRootNodeHandler(IClient client, IProvider provider, string baseAddres /// public override DLR_RESULT Start() { - //Wait until client connected if (WaitUntilConnected(Client, TimeoutMillis).IsBad()) { @@ -96,7 +98,6 @@ public override DLR_RESULT Start() return DLR_RESULT.DL_FAILED; } - //Create child handlers and add Handlers.Add(new MqttClientNodeHandler(this, this)); Handlers.Add(new MqttPubNodeHandler(this, this)); diff --git a/samples-net/datalayer.mqtt/Base/Names.cs b/samples-net/datalayer.mqtt/Base/Names.cs index 512bd08c..fdb13457 100644 --- a/samples-net/datalayer.mqtt/Base/Names.cs +++ b/samples-net/datalayer.mqtt/Base/Names.cs @@ -1,7 +1,7 @@ -/* +/* MIT License -Copyright (c) 2021-2022 Bosch Rexroth AG +Copyright (c) 2021-2023 Bosch Rexroth AG Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -33,7 +33,7 @@ internal static class Names public const string Topic = "topic"; public const string QualityOfService = "quality-of-service"; - public const string ServerAddress = "server-address"; + public const string BrokerAddress = "broker"; public const string Port = "port"; public const string ClientId = "client-id"; public const string Username = "username"; diff --git a/samples-net/datalayer.mqtt/Base/VariantExtensions.cs b/samples-net/datalayer.mqtt/Base/VariantExtensions.cs index 327fd6b8..9b2c4f8b 100644 --- a/samples-net/datalayer.mqtt/Base/VariantExtensions.cs +++ b/samples-net/datalayer.mqtt/Base/VariantExtensions.cs @@ -1,7 +1,7 @@ -/* +/* MIT License -Copyright (c) 2021-2022 Bosch Rexroth AG +Copyright (c) 2021-2023 Bosch Rexroth AG Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -131,6 +131,7 @@ public static string ToJson(this IVariant value) DLR_VARIANT_TYPE.DLR_VARIANT_TYPE_FLOAT32 => JsonSerializer.Serialize(value.ToFloat()), DLR_VARIANT_TYPE.DLR_VARIANT_TYPE_FLOAT64 => JsonSerializer.Serialize(value.ToDouble()), DLR_VARIANT_TYPE.DLR_VARIANT_TYPE_STRING => JsonSerializer.Serialize(value.ToString()), + DLR_VARIANT_TYPE.DLR_VARIANT_TYPE_TIMESTAMP => JsonSerializer.Serialize(value.ToDateTime()), //Flatbuffer -> JSON Array DLR_VARIANT_TYPE.DLR_VARIANT_TYPE_FLATBUFFERS => JsonSerializer.Serialize(value.ToFlatbuffers().ToSizedArray()), @@ -149,7 +150,7 @@ public static string ToJson(this IVariant value) DLR_VARIANT_TYPE.DLR_VARIANT_TYPE_ARRAY_OF_FLOAT32 => JsonSerializer.Serialize(value.ToFloatArray()), DLR_VARIANT_TYPE.DLR_VARIANT_TYPE_ARRAY_OF_FLOAT64 => JsonSerializer.Serialize(value.ToDoubleArray()), DLR_VARIANT_TYPE.DLR_VARIANT_TYPE_ARRAY_OF_STRING => JsonSerializer.Serialize(value.ToStringArray()), - + DLR_VARIANT_TYPE.DLR_VARIANT_TYPE_ARRAY_OF_TIMESTAMP => JsonSerializer.Serialize(value.ToDateTimeArray()), DLR_VARIANT_TYPE.DLR_VARIANT_TYPE_UNKNOWN => null, _ => null, }; diff --git a/samples-net/datalayer.mqtt/Client/MqttClientNodeHandler.cs b/samples-net/datalayer.mqtt/Client/MqttClientNodeHandler.cs index b384b41c..20a9463e 100644 --- a/samples-net/datalayer.mqtt/Client/MqttClientNodeHandler.cs +++ b/samples-net/datalayer.mqtt/Client/MqttClientNodeHandler.cs @@ -1,7 +1,7 @@ -/* +/* MIT License -Copyright (c) 2021-2022 Bosch Rexroth AG +Copyright (c) 2021-2023 Bosch Rexroth AG Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -25,7 +25,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE using Datalayer; using Samples.Datalayer.MQTT.Base; using System; -using System.Net; using System.Threading.Tasks; namespace Samples.Datalayer.MQTT.Client @@ -35,13 +34,6 @@ namespace Samples.Datalayer.MQTT.Client /// internal class MqttClientNodeHandler : MqttBaseNodeHandler { - // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - // !!! CHANGE THIS TO YOUR ENVIRONMENT !!! - // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - private static readonly IPAddress BrokerAddress = IPAddress.Parse("192.168.1.200"); - private static readonly string Username = ""; - private static readonly string Password = ""; - /// /// Creates a handler /// @@ -94,7 +86,7 @@ public override DLR_RESULT Start() //... //server-address - (result, node) = Root.Provider.CreateVariableNode(this, FullAddress, Names.ServerAddress, new Variant(BrokerAddress.ToString())); + (result, node) = Root.Provider.CreateVariableNode(this, FullAddress, Names.BrokerAddress, new Variant(Root.MqttClient.BrokerAddress)); if (result.IsBad()) { return DLR_RESULT.DL_FAILED; @@ -118,7 +110,7 @@ public override DLR_RESULT Start() Nodes.Add(node.Address, node); //username - (result, node) = Root.Provider.CreateVariableNode(this, FullAddress, Names.Username, new Variant(Username)); + (result, node) = Root.Provider.CreateVariableNode(this, FullAddress, Names.Username, new Variant(Root.MqttClient.Username)); if (result.IsBad()) { return DLR_RESULT.DL_FAILED; @@ -126,7 +118,7 @@ public override DLR_RESULT Start() Nodes.Add(node.Address, node); //password - (result, node) = Root.Provider.CreateVariableNode(this, FullAddress, Names.Password, new Variant(Password)); + (result, node) = Root.Provider.CreateVariableNode(this, FullAddress, Names.Password, new Variant(Root.MqttClient.Password)); if (result.IsBad()) { return DLR_RESULT.DL_FAILED; @@ -209,16 +201,17 @@ public override void OnWrite(string address, IVariant writeValue, IProviderNodeR return; } + //We're only interested in changed values var trimmedWriteValue = writeValue.Trim(); if (wrappedNode.Value == trimmedWriteValue) { - result.SetResult(DLR_RESULT.DL_FAILED); + result.SetResult(DLR_RESULT.DL_OK); return; } switch (wrappedNode.Name) { - case Names.ServerAddress: + case Names.BrokerAddress: if (writeValue.IsEmptyOrWhiteSpace()) { result.SetResult(DLR_RESULT.DL_FAILED); @@ -349,7 +342,7 @@ private DLR_RESULT UpdateStatus(DLR_RESULT result) /// private async Task ConnectMqttAsync() { - Root.MqttClient.ServerAddress = GetNode(Names.ServerAddress).Value.ToString(); + Root.MqttClient.BrokerAddress = GetNode(Names.BrokerAddress).Value.ToString(); Root.MqttClient.Port = GetNode(Names.Port).Value.ToInt32(); Root.MqttClient.ClientId = GetNode(Names.ClientId).Value.ToString(); Root.MqttClient.CleanSession = GetNode(Names.CleanSession).Value.ToBool(); diff --git a/samples-net/datalayer.mqtt/Client/MqttClientWrapper.cs b/samples-net/datalayer.mqtt/Client/MqttClientWrapper.cs index 90859fa6..ae2eb202 100644 --- a/samples-net/datalayer.mqtt/Client/MqttClientWrapper.cs +++ b/samples-net/datalayer.mqtt/Client/MqttClientWrapper.cs @@ -1,8 +1,8 @@ - + /* MIT License -Copyright (c) 2021-2022 Bosch Rexroth AG +Copyright (c) 2021-2023 Bosch Rexroth AG Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -70,6 +70,7 @@ internal sealed class MqttClientWrapper /// /// Creates a MQTT client wrapper /// + /// public MqttClientWrapper() { //Create client @@ -84,17 +85,17 @@ public MqttClientWrapper() #region Properties /// - /// Gets or sets the Server Address + /// Gets or sets the broker address /// - public string ServerAddress { get; set; } = "192.168.1.200"; + public string BrokerAddress { get; set; } = ""; /// - /// Gets or sets the Port + /// Gets or sets the port /// public int Port { get; set; } = 1883; /// - /// Sets or sets the ClientId + /// Sets or sets the client ID /// public string ClientId { get; set; } = ""; @@ -114,7 +115,7 @@ public MqttClientWrapper() public TimeSpan CommunicationTimeout { get; set; } = TimeSpan.FromMilliseconds(10_000); /// - /// + /// Gets or sets the keepalive period /// public TimeSpan KeepAlivePeriod { get; set; } = TimeSpan.FromMilliseconds(10_000); @@ -152,11 +153,11 @@ public async Task ConnectAsync() try { - Console.WriteLine($"Connecting to MQTT Broker: {ServerAddress}, ClientId: {ClientId}, CleanSession: {CleanSession} ..."); + Console.WriteLine($"Connecting to MQTT Broker: {BrokerAddress}, ClientId: {ClientId}, CleanSession: {CleanSession} ..."); //Run a MQTT publish client var task = _client.ConnectAsync(new MqttClientOptionsBuilder() - .WithTcpServer(ServerAddress, Port) + .WithTcpServer(BrokerAddress, Port) .WithClientId(ClientId) .WithProtocolVersion(MqttProtocolVersion.V500) //Version 5 is Mandatory, because we make use of the SubscriptionIdentifier feature .WithCleanSession(CleanSession) @@ -166,19 +167,19 @@ public async Task ConnectAsync() //.WithSessionExpiryInterval(60000) //.WithTls() .WithNoKeepAlive() - .Build()); ; + .Build()); var result = await task; //Failed if (result.ResultCode != MqttClientConnectResultCode.Success) { - Console.WriteLine($"Failed to connect to MQTT Broker: {ServerAddress}, Result: {result.ResultCode}"); + Console.WriteLine($"Failed to connect to MQTT Broker: {BrokerAddress}, Result: {result.ResultCode}"); return DLR_RESULT.DL_FAILED; } //Success - Console.WriteLine($"Connected to MQTT Broker: {ServerAddress}"); + Console.WriteLine($"Connected to MQTT Broker: {BrokerAddress}"); return DLR_RESULT.DL_OK; } catch (OperationCanceledException exc) @@ -213,7 +214,7 @@ public async Task DisconnectAsync() try { - Console.WriteLine($"Disconnecting from MQTT Broker: {ServerAddress} ..."); + Console.WriteLine($"Disconnecting from MQTT Broker: {BrokerAddress} ..."); var task = _client.DisconnectAsync(options); await task; @@ -446,7 +447,10 @@ public static bool IsValidProtocolVersion(int protocolVersion) /// Returns a default client id /// /// - public static string DefaultClientId() => Dns.GetHostName() + "_" + DateTime.Now.Ticks.ToString(); + public static string DefaultClientId() + { + return Dns.GetHostName() + "_" + DateTime.Now.Ticks.ToString(); + } /// /// Returns a default topic diff --git a/samples-net/datalayer.mqtt/Program.cs b/samples-net/datalayer.mqtt/Program.cs index a27d4baa..4826d543 100644 --- a/samples-net/datalayer.mqtt/Program.cs +++ b/samples-net/datalayer.mqtt/Program.cs @@ -1,7 +1,7 @@ /* MIT License -Copyright (c) 2021-2022 Bosch Rexroth AG +Copyright (c) 2021-2023 Bosch Rexroth AG Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -45,22 +45,19 @@ static void Main(string[] args) system.Start(startBroker: false); Console.WriteLine("ctrlX Data Layer system started."); - // Create a connection string with the parameters according to your environment (see Remote class) - var clientConnectionString = new Remote(ip: "192.168.1.1", sslPort: 443).ToString(); + // Create a remote address with the parameters according to your environment + var remote = new Remote(ip: "192.168.1.1", sslPort: 443).ToString(); // Create the client with remote connection string - using var client = system.Factory.CreateClient(clientConnectionString); + using var client = system.Factory.CreateClient(remote); Console.WriteLine("ctrlX Data Layer client created."); - // Create a connection string with the parameters according to your environment (see Remote class) - var providerConnectionString = new Remote(ip: "192.168.1.1", sslPort: 443).ToString(); - // Create the provider with remote connection string - using var provider = system.Factory.CreateProvider(providerConnectionString); + using var provider = system.Factory.CreateProvider(remote); Console.WriteLine("ctrlX Data Layer provider created."); //Create root node handler - _mqttRootNodeHandler = new MqttRootNodeHandler(client, provider, "samples", "mqtt"); + _mqttRootNodeHandler = new MqttRootNodeHandler(client, provider, "127.0.0.1", "samples", "mqtt"); //Start the handler if (_mqttRootNodeHandler.Start().IsBad()) diff --git a/samples-net/datalayer.mqtt/Pub/MqttPubConfigNodeHandler.cs b/samples-net/datalayer.mqtt/Pub/MqttPubConfigNodeHandler.cs index 58deaa9c..7f8d6ec2 100644 --- a/samples-net/datalayer.mqtt/Pub/MqttPubConfigNodeHandler.cs +++ b/samples-net/datalayer.mqtt/Pub/MqttPubConfigNodeHandler.cs @@ -1,7 +1,7 @@ -/* +/* MIT License -Copyright (c) 2021-2022 Bosch Rexroth AG +Copyright (c) 2021-2023 Bosch Rexroth AG Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -24,7 +24,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE using comm.datalayer; using Datalayer; -using FlatBuffers; +using Google.FlatBuffers; using MQTTnet.Protocol; using Samples.Datalayer.MQTT.Base; using Samples.Datalayer.MQTT.Client; @@ -181,7 +181,7 @@ public override void OnWrite(string address, IVariant writeValue, IProviderNodeR var trimmedWriteValue = writeValue.Trim(); if (wrappedNode.Value == trimmedWriteValue) { - result.SetResult(DLR_RESULT.DL_FAILED); + result.SetResult(DLR_RESULT.DL_OK); return; } @@ -483,8 +483,7 @@ private async Task PublishMqttAsync(string address, IVariant value) messageExpiryIntervalMillis: GetNode(Names.MessageExpiryIntervalMillis).Value.ToUInt32(), retain: GetNode(Names.Retain).Value.ToBool()); - var result = await task; - return result; + return await task; } #endregion diff --git a/samples-net/datalayer.mqtt/Pub/MqttPubNodeHandler.cs b/samples-net/datalayer.mqtt/Pub/MqttPubNodeHandler.cs index 13bafb30..01c8db22 100644 --- a/samples-net/datalayer.mqtt/Pub/MqttPubNodeHandler.cs +++ b/samples-net/datalayer.mqtt/Pub/MqttPubNodeHandler.cs @@ -1,7 +1,7 @@ -/* +/* MIT License -Copyright (c) 2021-2022 Bosch Rexroth AG +Copyright (c) 2021-2023 Bosch Rexroth AG Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -100,7 +100,7 @@ public override void OnWrite(string address, IVariant writeValue, IProviderNodeR var trimmedWriteValue = writeValue.Trim(); if (wrappedNode.Value == trimmedWriteValue) { - result.SetResult(DLR_RESULT.DL_FAILED); + result.SetResult(DLR_RESULT.DL_OK); return; } diff --git a/samples-net/datalayer.mqtt/Sub/MqttSubConfigNodeHandler.cs b/samples-net/datalayer.mqtt/Sub/MqttSubConfigNodeHandler.cs index e009a2b2..09369818 100644 --- a/samples-net/datalayer.mqtt/Sub/MqttSubConfigNodeHandler.cs +++ b/samples-net/datalayer.mqtt/Sub/MqttSubConfigNodeHandler.cs @@ -1,7 +1,7 @@ -/* +/* MIT License -Copyright (c) 2021-2022 Bosch Rexroth AG +Copyright (c) 2021-2023 Bosch Rexroth AG Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -140,7 +140,7 @@ public override void OnWrite(string address, IVariant writeValue, IProviderNodeR var trimmedWriteValue = writeValue.Trim(); if (wrappedNode.Value == trimmedWriteValue) { - result.SetResult(DLR_RESULT.DL_FAILED); + result.SetResult(DLR_RESULT.DL_OK); return; } diff --git a/samples-net/datalayer.mqtt/Sub/MqttSubNodeHandler.cs b/samples-net/datalayer.mqtt/Sub/MqttSubNodeHandler.cs index 8f9e207c..ab74e895 100644 --- a/samples-net/datalayer.mqtt/Sub/MqttSubNodeHandler.cs +++ b/samples-net/datalayer.mqtt/Sub/MqttSubNodeHandler.cs @@ -1,4 +1,4 @@ -/* +/* MIT License Copyright (c) 2021-2022 Bosch Rexroth AG @@ -99,7 +99,7 @@ public override void OnWrite(string address, IVariant writeValue, IProviderNodeR var trimmedWriteValue = writeValue.Trim(); if (wrappedNode.Value == trimmedWriteValue) { - result.SetResult(DLR_RESULT.DL_FAILED); + result.SetResult(DLR_RESULT.DL_OK); return; } diff --git a/samples-net/datalayer.mqtt/Sub/MqttSubScannerNodeHandler.cs b/samples-net/datalayer.mqtt/Sub/MqttSubScannerNodeHandler.cs index 69f85a39..3582bf28 100644 --- a/samples-net/datalayer.mqtt/Sub/MqttSubScannerNodeHandler.cs +++ b/samples-net/datalayer.mqtt/Sub/MqttSubScannerNodeHandler.cs @@ -1,7 +1,7 @@ -/* +/* MIT License -Copyright (c) 2021-2022 Bosch Rexroth AG +Copyright (c) 2021-2023 Bosch Rexroth AG Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -24,7 +24,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE using comm.datalayer; using Datalayer; -using FlatBuffers; +using Google.FlatBuffers; using MQTTnet; using MQTTnet.Protocol; using Samples.Datalayer.MQTT.Base; @@ -43,13 +43,14 @@ internal class MqttSubScannerNodeHandler : MqttSubBaseNodeHandler // If we know how many items we want to insert into the ConcurrentDictionary, // set the initial capacity to some prime number above that, to ensure that // the ConcurrentDictionary does not need to be resized while initializing it. - private static readonly int InitialCapacity = 101; + private const int InitialCapacity = 101; // The higher the concurrencyLevel, the higher the theoretical number of operations // that could be performed concurrently on the ConcurrentDictionary. However, global // operations like resizing the dictionary take longer as the concurrencyLevel rises. // For the purposes of this example, we'll compromise at numCores * 2. private static readonly int ConcurrencyLevel = Environment.ProcessorCount * 2; + /// /// Represents a virtual light-weight MQTT Node /// @@ -247,7 +248,6 @@ protected override void OnMessageReceived(MqttApplicationMessageReceivedEventArg //Create a Variant of best matching type (Supported int32, double, string) var value = ToVariant(stringifiedPayload); var address = $"{FullAddress}/{args.ApplicationMessage.Topic}"; - //var node = new MqttNode(address, value); //Add node if not existing or update with current value _nodes.AddOrUpdate(address, value, (k, v) => value); diff --git a/samples-net/datalayer.mqtt/datalayer.mqtt.csproj b/samples-net/datalayer.mqtt/datalayer.mqtt.csproj index 4941eeb4..3915a477 100644 --- a/samples-net/datalayer.mqtt/datalayer.mqtt.csproj +++ b/samples-net/datalayer.mqtt/datalayer.mqtt.csproj @@ -8,10 +8,8 @@ - - - - + + diff --git a/samples-net/datalayer.provider.alldata/.vscode/tasks.json b/samples-net/datalayer.provider.alldata/.vscode/tasks.json index a376d9bb..79e04b37 100644 --- a/samples-net/datalayer.provider.alldata/.vscode/tasks.json +++ b/samples-net/datalayer.provider.alldata/.vscode/tasks.json @@ -1,55 +1,228 @@ { - "version": "2.0.0", - "tasks": [ - { - "label": "build snap amd64", - "type": "shell", - "command": "bash", - "args": [ - "build-snap-amd64.sh" - ], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build snap arm64", - "type": "shell", - "command": "bash", - "args": [ - "build-snap-arm64.sh" - ], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build project", - "command": "dotnet", - "type": "process", - "args": [ - "build", - "${workspaceFolder}/datalayer.provider.alldata.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary" - ], - "problemMatcher": "$msCompile" - }, - { - "label": "clean project", - "command": "dotnet", - "type": "process", - "args": [ - "clean", - "${workspaceFolder}/datalayer.provider.alldata.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary" - ], - "problemMatcher": "$msCompile" - } - ] + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "build project", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/datalayer.provider.alldata.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "clean project", + "command": "dotnet", + "type": "process", + "args": [ + "clean", + "${workspaceFolder}/datalayer.provider.alldata.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "Build snap amd64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-amd64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build snap arm64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-arm64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + ], + "inputs": [ + { + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", + "type": "promptString", + "description": "IP address", + "default": "192.168.1.1" + }, + { + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", + "type": "promptString", + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" + }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" + } + ] } \ No newline at end of file diff --git a/samples-net/datalayer.provider.alldata/Node.cs b/samples-net/datalayer.provider.alldata/Node.cs index b50adeb8..ae8c6500 100644 --- a/samples-net/datalayer.provider.alldata/Node.cs +++ b/samples-net/datalayer.provider.alldata/Node.cs @@ -26,7 +26,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE namespace Samples.Datalayer.Provider.Alldata { - using FlatBuffers; + using Google.FlatBuffers; using sample.schema; using System; using System.Linq; diff --git a/samples-net/datalayer.provider.alldata/Program.cs b/samples-net/datalayer.provider.alldata/Program.cs index d7ea28ae..3202f802 100644 --- a/samples-net/datalayer.provider.alldata/Program.cs +++ b/samples-net/datalayer.provider.alldata/Program.cs @@ -1,7 +1,7 @@ /* MIT License -Copyright (c) 2021-2022 Bosch Rexroth AG +Copyright (c) 2021-2023 Bosch Rexroth AG Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -27,7 +27,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE namespace Samples.Datalayer.Provider.Alldata { using comm.datalayer; - using FlatBuffers; + using Google.FlatBuffers; using sample.schema; using System; using System.IO; @@ -56,11 +56,11 @@ internal static void Main(string[] args) system.Start(); Console.WriteLine("ctrlX Data Layer system started."); - // Create a connection string with the parameters according to your environment (see Remote class) - var connectionString = new Remote(ip: "192.168.1.1", sslPort: 443).ToString(); + // Create a remote address with the parameters according to your environment + var remote = new Remote(ip: "192.168.1.1", sslPort: 443).ToString(); // Create the provider with remote connection string - using var provider = system.Factory.CreateProvider(connectionString); + using var provider = system.Factory.CreateProvider(remote); // Register type with binary flatbuffers schema file: sampleSchema.bfbs (auto generated from sampleSchema.fbs by flatc compiler) var resultRegisterType = provider.RegisterType(DataTypes.InertialValue.Address, Path.Combine(AppContext.BaseDirectory, "sampleSchema.bfbs")); diff --git a/samples-net/datalayer.provider.alldata/datalayer.provider.alldata.csproj b/samples-net/datalayer.provider.alldata/datalayer.provider.alldata.csproj index 411aeac0..3295a881 100644 --- a/samples-net/datalayer.provider.alldata/datalayer.provider.alldata.csproj +++ b/samples-net/datalayer.provider.alldata/datalayer.provider.alldata.csproj @@ -8,10 +8,8 @@ - - - - + + diff --git a/samples-net/datalayer.provider.alldata/sample/schema/InertialValue.cs b/samples-net/datalayer.provider.alldata/sample/schema/InertialValue.cs index bf55d6c6..685fdddf 100644 --- a/samples-net/datalayer.provider.alldata/sample/schema/InertialValue.cs +++ b/samples-net/datalayer.provider.alldata/sample/schema/InertialValue.cs @@ -5,46 +5,93 @@ namespace sample.schema { -using global::System; -using global::System.Collections.Generic; -using global::FlatBuffers; + using global::System; + using global::System.Collections.Generic; + using global::Google.FlatBuffers; -public struct InertialValue : IFlatbufferObject -{ - private Table __p; - public ByteBuffer ByteBuffer { get { return __p.bb; } } - public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_12_0(); } - public static InertialValue GetRootAsInertialValue(ByteBuffer _bb) { return GetRootAsInertialValue(_bb, new InertialValue()); } - public static InertialValue GetRootAsInertialValue(ByteBuffer _bb, InertialValue obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); } - public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); } - public InertialValue __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } - - public short X { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetShort(o + __p.bb_pos) : (short)0; } } - public short Y { get { int o = __p.__offset(6); return o != 0 ? __p.bb.GetShort(o + __p.bb_pos) : (short)0; } } - public short Z { get { int o = __p.__offset(8); return o != 0 ? __p.bb.GetShort(o + __p.bb_pos) : (short)0; } } - - public static Offset CreateInertialValue(FlatBufferBuilder builder, - short x = 0, - short y = 0, - short z = 0) { - builder.StartTable(3); - InertialValue.AddZ(builder, z); - InertialValue.AddY(builder, y); - InertialValue.AddX(builder, x); - return InertialValue.EndInertialValue(builder); - } - - public static void StartInertialValue(FlatBufferBuilder builder) { builder.StartTable(3); } - public static void AddX(FlatBufferBuilder builder, short x) { builder.AddShort(0, x, 0); } - public static void AddY(FlatBufferBuilder builder, short y) { builder.AddShort(1, y, 0); } - public static void AddZ(FlatBufferBuilder builder, short z) { builder.AddShort(2, z, 0); } - public static Offset EndInertialValue(FlatBufferBuilder builder) { - int o = builder.EndTable(); - return new Offset(o); - } - public static void FinishInertialValueBuffer(FlatBufferBuilder builder, Offset offset) { builder.Finish(offset.Value); } - public static void FinishSizePrefixedInertialValueBuffer(FlatBufferBuilder builder, Offset offset) { builder.FinishSizePrefixed(offset.Value); } -}; + public struct InertialValue : IFlatbufferObject + { + private Table __p; + public ByteBuffer ByteBuffer { get { return __p.bb; } } + public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_3_3(); } + public static InertialValue GetRootAsInertialValue(ByteBuffer _bb) { return GetRootAsInertialValue(_bb, new InertialValue()); } + public static InertialValue GetRootAsInertialValue(ByteBuffer _bb, InertialValue obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); } + public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); } + public InertialValue __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } + + public short X { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetShort(o + __p.bb_pos) : (short)0; } } + public short Y { get { int o = __p.__offset(6); return o != 0 ? __p.bb.GetShort(o + __p.bb_pos) : (short)0; } } + public short Z { get { int o = __p.__offset(8); return o != 0 ? __p.bb.GetShort(o + __p.bb_pos) : (short)0; } } + + public static Offset CreateInertialValue(FlatBufferBuilder builder, + short x = 0, + short y = 0, + short z = 0) + { + builder.StartTable(3); + InertialValue.AddZ(builder, z); + InertialValue.AddY(builder, y); + InertialValue.AddX(builder, x); + return InertialValue.EndInertialValue(builder); + } + + public static void StartInertialValue(FlatBufferBuilder builder) { builder.StartTable(3); } + public static void AddX(FlatBufferBuilder builder, short x) { builder.AddShort(0, x, 0); } + public static void AddY(FlatBufferBuilder builder, short y) { builder.AddShort(1, y, 0); } + public static void AddZ(FlatBufferBuilder builder, short z) { builder.AddShort(2, z, 0); } + public static Offset EndInertialValue(FlatBufferBuilder builder) + { + int o = builder.EndTable(); + return new Offset(o); + } + public static void FinishInertialValueBuffer(FlatBufferBuilder builder, Offset offset) { builder.Finish(offset.Value); } + public static void FinishSizePrefixedInertialValueBuffer(FlatBufferBuilder builder, Offset offset) { builder.FinishSizePrefixed(offset.Value); } + public InertialValueT UnPack() + { + var _o = new InertialValueT(); + this.UnPackTo(_o); + return _o; + } + public void UnPackTo(InertialValueT _o) + { + _o.X = this.X; + _o.Y = this.Y; + _o.Z = this.Z; + } + public static Offset Pack(FlatBufferBuilder builder, InertialValueT _o) + { + if (_o == null) return default(Offset); + return CreateInertialValue( + builder, + _o.X, + _o.Y, + _o.Z); + } + } + + public class InertialValueT + { + public short X { get; set; } + public short Y { get; set; } + public short Z { get; set; } + + public InertialValueT() + { + this.X = 0; + this.Y = 0; + this.Z = 0; + } + public static InertialValueT DeserializeFromBinary(byte[] fbBuffer) + { + return InertialValue.GetRootAsInertialValue(new ByteBuffer(fbBuffer)).UnPack(); + } + public byte[] SerializeToBinary() + { + var fbb = new FlatBufferBuilder(0x10000); + InertialValue.FinishInertialValueBuffer(fbb, InertialValue.Pack(fbb, this)); + return fbb.DataBuffer.ToSizedArray(); + } + } } diff --git a/samples-net/datalayer.provider.alldata/snap/snapcraft.yaml b/samples-net/datalayer.provider.alldata/snap/snapcraft.yaml index 69f3c6d1..0e6da57d 100644 --- a/samples-net/datalayer.provider.alldata/snap/snapcraft.yaml +++ b/samples-net/datalayer.provider.alldata/snap/snapcraft.yaml @@ -21,7 +21,7 @@ apps: app: command: datalayer.provider.alldata # interfaces to connect to https://snapcraft.io/docs/supported-interfaces - plugs: [network, network-status, network-bind, process-control] + plugs: [network, network-status, network-bind] daemon: simple restart-condition: always passthrough: diff --git a/samples-net/datalayer.provider.virtual/.vscode/tasks.json b/samples-net/datalayer.provider.virtual/.vscode/tasks.json index e121c4d9..6b6df449 100644 --- a/samples-net/datalayer.provider.virtual/.vscode/tasks.json +++ b/samples-net/datalayer.provider.virtual/.vscode/tasks.json @@ -1,55 +1,228 @@ { - "version": "2.0.0", - "tasks": [ - { - "label": "build snap amd64", - "type": "shell", - "command": "bash", - "args": [ - "build-snap-amd64.sh" - ], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build snap arm64", - "type": "shell", - "command": "bash", - "args": [ - "build-snap-arm64.sh" - ], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build project", - "command": "dotnet", - "type": "process", - "args": [ - "build", - "${workspaceFolder}/datalayer.provider.virtual.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary" - ], - "problemMatcher": "$msCompile" - }, - { - "label": "clean project", - "command": "dotnet", - "type": "process", - "args": [ - "clean", - "${workspaceFolder}/datalayer.provider.virtual.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary" - ], - "problemMatcher": "$msCompile" - } - ] + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "build project", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/datalayer.provider.virtual.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "clean project", + "command": "dotnet", + "type": "process", + "args": [ + "clean", + "${workspaceFolder}/datalayer.provider.virtual.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "Build snap amd64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-amd64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build snap arm64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-arm64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + ], + "inputs": [ + { + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", + "type": "promptString", + "description": "IP address", + "default": "192.168.1.1" + }, + { + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", + "type": "promptString", + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" + }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" + } + ] } \ No newline at end of file diff --git a/samples-net/datalayer.provider.virtual/Program.cs b/samples-net/datalayer.provider.virtual/Program.cs index b19e39b0..3a317883 100644 --- a/samples-net/datalayer.provider.virtual/Program.cs +++ b/samples-net/datalayer.provider.virtual/Program.cs @@ -1,7 +1,7 @@ /* MIT License -Copyright (c) 2021-2022 Bosch Rexroth AG +Copyright (c) 2021-2023 Bosch Rexroth AG Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -42,11 +42,11 @@ static void Main(string[] args) system.Start(startBroker: false); Console.WriteLine("ctrlX Data Layer system started."); - // Create a connection string with the parameters according to your environment (see Remote class) - var connectionString = new Remote(ip: "192.168.1.1", sslPort: 443).ToString(); + // Create a remote address with the parameters according to your environment + var remote = new Remote(ip: "192.168.1.1", sslPort: 443).ToString(); // Create the provider with remote connection string - using var provider = system.Factory.CreateProvider(connectionString); + using var provider = system.Factory.CreateProvider(remote); Console.WriteLine("ctrlX Data Layer provider created."); //Create root node handler diff --git a/samples-net/datalayer.provider.virtual/Properties/launchSettings.json b/samples-net/datalayer.provider.virtual/Properties/launchSettings.json new file mode 100644 index 00000000..3b41b835 --- /dev/null +++ b/samples-net/datalayer.provider.virtual/Properties/launchSettings.json @@ -0,0 +1,8 @@ +{ + "profiles": { + "datalayer.provider.virtual": { + "commandName": "Project", + "nativeDebugging": false + } + } +} \ No newline at end of file diff --git a/samples-net/datalayer.provider.virtual/VirtualNodeHandler.cs b/samples-net/datalayer.provider.virtual/VirtualNodeHandler.cs index 9deb2cf9..89f2b5f6 100644 --- a/samples-net/datalayer.provider.virtual/VirtualNodeHandler.cs +++ b/samples-net/datalayer.provider.virtual/VirtualNodeHandler.cs @@ -1,7 +1,7 @@ -/* +/* MIT License -Copyright (c) 2021-2022 Bosch Rexroth AG +Copyright (c) 2021-2023 Bosch Rexroth AG Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -24,7 +24,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE using comm.datalayer; using Datalayer; -using FlatBuffers; +using Google.FlatBuffers; using System; using System.Collections.Concurrent; using System.Linq; @@ -37,11 +37,10 @@ namespace Samples.Datalayer.Provider.Virtual /// internal class VirtualNodeHandler : IProviderNodeHandler { - // If we know how many items we want to insert into the ConcurrentDictionary, // set the initial capacity to some prime number above that, to ensure that // the ConcurrentDictionary does not need to be resized while initializing it. - private static readonly int InitialCapacity = 101; + private const int InitialCapacity = 101; // The higher the concurrencyLevel, the higher the theoretical number of operations // that could be performed concurrently on the ConcurrentDictionary. However, global @@ -117,7 +116,6 @@ public VirtualNodeHandler(IProvider provider, string baseAddress, string name) /// public DLR_RESULT Start() { - //We just listen to our base address using a wildcard on '{FullAddress}/**' var (result, _) = Provider.CreateNode(FullAddress, "**", this); if (result.IsBad()) @@ -128,6 +126,7 @@ public DLR_RESULT Start() _nodes.AddOrUpdate(folderNode.Address, folderNode, (k, v) => folderNode); //Create some virtual nodes here just for demonstration + Console.WriteLine($"Creating virtual nodes on address: {FullAddress}"); int currentLevel = 0; if (CreateDummyNodes(FullAddress, 3, ref currentLevel, 5).IsBad()) { @@ -307,8 +306,6 @@ private DLR_RESULT CreateDummyNodes(string currentPath, int nodesPerLevel, ref i var virtualNode = new VirtualNode(address, new Variant(_random.Next()), NodeClass.Variable, true, true, false, false, false); _nodes.AddOrUpdate(address, virtualNode, (k, v) => virtualNode); - Console.WriteLine($"Created a virtual node on address: {address}"); - if (currentLevel < maxDepth) { CreateDummyNodes(address, nodesPerLevel, ref currentLevel, maxDepth); diff --git a/samples-net/datalayer.provider.virtual/datalayer.provider.virtual.csproj b/samples-net/datalayer.provider.virtual/datalayer.provider.virtual.csproj index 4d6a0f8a..06ab8f0a 100644 --- a/samples-net/datalayer.provider.virtual/datalayer.provider.virtual.csproj +++ b/samples-net/datalayer.provider.virtual/datalayer.provider.virtual.csproj @@ -18,10 +18,8 @@ - - - - + + diff --git a/samples-net/datalayer.provider/.vscode/tasks.json b/samples-net/datalayer.provider/.vscode/tasks.json index b38397fd..7e5f81f8 100644 --- a/samples-net/datalayer.provider/.vscode/tasks.json +++ b/samples-net/datalayer.provider/.vscode/tasks.json @@ -1,55 +1,228 @@ { - "version": "2.0.0", - "tasks": [ - { - "label": "build snap amd64", - "type": "shell", - "command": "bash", - "args": [ - "build-snap-amd64.sh" - ], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build snap arm64", - "type": "shell", - "command": "bash", - "args": [ - "build-snap-arm64.sh" - ], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build project", - "command": "dotnet", - "type": "process", - "args": [ - "build", - "${workspaceFolder}/datalayer.provider.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary" - ], - "problemMatcher": "$msCompile" - }, - { - "label": "clean project", - "command": "dotnet", - "type": "process", - "args": [ - "clean", - "${workspaceFolder}/datalayer.provider.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary" - ], - "problemMatcher": "$msCompile" - } - ] + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "build project", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/datalayer.provider.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "clean project", + "command": "dotnet", + "type": "process", + "args": [ + "clean", + "${workspaceFolder}/datalayer.provider.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "Build snap amd64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-amd64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build snap arm64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-arm64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + ], + "inputs": [ + { + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", + "type": "promptString", + "description": "IP address", + "default": "192.168.1.1" + }, + { + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", + "type": "promptString", + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" + }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" + } + ] } \ No newline at end of file diff --git a/samples-net/datalayer.provider/Program.cs b/samples-net/datalayer.provider/Program.cs index 14df4c1f..21ef2dc4 100644 --- a/samples-net/datalayer.provider/Program.cs +++ b/samples-net/datalayer.provider/Program.cs @@ -1,7 +1,7 @@ /* MIT License -Copyright (c) 2021-2022 Bosch Rexroth AG +Copyright (c) 2021-2023 Bosch Rexroth AG Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -27,7 +27,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE namespace Samples.Datalayer.Provider { using comm.datalayer; - using FlatBuffers; + using Google.FlatBuffers; using sample.schema; using System; using System.IO; @@ -54,11 +54,11 @@ internal static void Main(string[] args) system.Start(startBroker: false); Console.WriteLine("ctrlX Data Layer system started."); - // Create a connection string with the parameters according to your environment (see Remote class) - var connectionString = new Remote(ip: "192.168.1.1", sslPort: 443).ToString(); + // Create a remote address with the parameters according to your environment + var remote = new Remote(ip: "192.168.1.1", sslPort: 443).ToString(); // Create the provider with remote connection string - using var provider = system.Factory.CreateProvider(connectionString); + using var provider = system.Factory.CreateProvider(remote); Console.WriteLine("ctrlX Data Layer provider created."); // Create and register node on given address and read-only callbacks. diff --git a/samples-net/datalayer.provider/Properties/launchSettings.json b/samples-net/datalayer.provider/Properties/launchSettings.json new file mode 100644 index 00000000..8f657da9 --- /dev/null +++ b/samples-net/datalayer.provider/Properties/launchSettings.json @@ -0,0 +1,8 @@ +{ + "profiles": { + "datalayer.provider": { + "commandName": "Project", + "nativeDebugging": false + } + } +} \ No newline at end of file diff --git a/samples-net/datalayer.provider/datalayer.provider.csproj b/samples-net/datalayer.provider/datalayer.provider.csproj index 6c76332a..f4822a3a 100644 --- a/samples-net/datalayer.provider/datalayer.provider.csproj +++ b/samples-net/datalayer.provider/datalayer.provider.csproj @@ -8,10 +8,8 @@ - - - - + + diff --git a/samples-net/datalayer.provider/sample/schema/InertialValue.cs b/samples-net/datalayer.provider/sample/schema/InertialValue.cs index bf55d6c6..685fdddf 100644 --- a/samples-net/datalayer.provider/sample/schema/InertialValue.cs +++ b/samples-net/datalayer.provider/sample/schema/InertialValue.cs @@ -5,46 +5,93 @@ namespace sample.schema { -using global::System; -using global::System.Collections.Generic; -using global::FlatBuffers; + using global::System; + using global::System.Collections.Generic; + using global::Google.FlatBuffers; -public struct InertialValue : IFlatbufferObject -{ - private Table __p; - public ByteBuffer ByteBuffer { get { return __p.bb; } } - public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_12_0(); } - public static InertialValue GetRootAsInertialValue(ByteBuffer _bb) { return GetRootAsInertialValue(_bb, new InertialValue()); } - public static InertialValue GetRootAsInertialValue(ByteBuffer _bb, InertialValue obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); } - public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); } - public InertialValue __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } - - public short X { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetShort(o + __p.bb_pos) : (short)0; } } - public short Y { get { int o = __p.__offset(6); return o != 0 ? __p.bb.GetShort(o + __p.bb_pos) : (short)0; } } - public short Z { get { int o = __p.__offset(8); return o != 0 ? __p.bb.GetShort(o + __p.bb_pos) : (short)0; } } - - public static Offset CreateInertialValue(FlatBufferBuilder builder, - short x = 0, - short y = 0, - short z = 0) { - builder.StartTable(3); - InertialValue.AddZ(builder, z); - InertialValue.AddY(builder, y); - InertialValue.AddX(builder, x); - return InertialValue.EndInertialValue(builder); - } - - public static void StartInertialValue(FlatBufferBuilder builder) { builder.StartTable(3); } - public static void AddX(FlatBufferBuilder builder, short x) { builder.AddShort(0, x, 0); } - public static void AddY(FlatBufferBuilder builder, short y) { builder.AddShort(1, y, 0); } - public static void AddZ(FlatBufferBuilder builder, short z) { builder.AddShort(2, z, 0); } - public static Offset EndInertialValue(FlatBufferBuilder builder) { - int o = builder.EndTable(); - return new Offset(o); - } - public static void FinishInertialValueBuffer(FlatBufferBuilder builder, Offset offset) { builder.Finish(offset.Value); } - public static void FinishSizePrefixedInertialValueBuffer(FlatBufferBuilder builder, Offset offset) { builder.FinishSizePrefixed(offset.Value); } -}; + public struct InertialValue : IFlatbufferObject + { + private Table __p; + public ByteBuffer ByteBuffer { get { return __p.bb; } } + public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_3_3(); } + public static InertialValue GetRootAsInertialValue(ByteBuffer _bb) { return GetRootAsInertialValue(_bb, new InertialValue()); } + public static InertialValue GetRootAsInertialValue(ByteBuffer _bb, InertialValue obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); } + public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); } + public InertialValue __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } + + public short X { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetShort(o + __p.bb_pos) : (short)0; } } + public short Y { get { int o = __p.__offset(6); return o != 0 ? __p.bb.GetShort(o + __p.bb_pos) : (short)0; } } + public short Z { get { int o = __p.__offset(8); return o != 0 ? __p.bb.GetShort(o + __p.bb_pos) : (short)0; } } + + public static Offset CreateInertialValue(FlatBufferBuilder builder, + short x = 0, + short y = 0, + short z = 0) + { + builder.StartTable(3); + InertialValue.AddZ(builder, z); + InertialValue.AddY(builder, y); + InertialValue.AddX(builder, x); + return InertialValue.EndInertialValue(builder); + } + + public static void StartInertialValue(FlatBufferBuilder builder) { builder.StartTable(3); } + public static void AddX(FlatBufferBuilder builder, short x) { builder.AddShort(0, x, 0); } + public static void AddY(FlatBufferBuilder builder, short y) { builder.AddShort(1, y, 0); } + public static void AddZ(FlatBufferBuilder builder, short z) { builder.AddShort(2, z, 0); } + public static Offset EndInertialValue(FlatBufferBuilder builder) + { + int o = builder.EndTable(); + return new Offset(o); + } + public static void FinishInertialValueBuffer(FlatBufferBuilder builder, Offset offset) { builder.Finish(offset.Value); } + public static void FinishSizePrefixedInertialValueBuffer(FlatBufferBuilder builder, Offset offset) { builder.FinishSizePrefixed(offset.Value); } + public InertialValueT UnPack() + { + var _o = new InertialValueT(); + this.UnPackTo(_o); + return _o; + } + public void UnPackTo(InertialValueT _o) + { + _o.X = this.X; + _o.Y = this.Y; + _o.Z = this.Z; + } + public static Offset Pack(FlatBufferBuilder builder, InertialValueT _o) + { + if (_o == null) return default(Offset); + return CreateInertialValue( + builder, + _o.X, + _o.Y, + _o.Z); + } + } + + public class InertialValueT + { + public short X { get; set; } + public short Y { get; set; } + public short Z { get; set; } + + public InertialValueT() + { + this.X = 0; + this.Y = 0; + this.Z = 0; + } + public static InertialValueT DeserializeFromBinary(byte[] fbBuffer) + { + return InertialValue.GetRootAsInertialValue(new ByteBuffer(fbBuffer)).UnPack(); + } + public byte[] SerializeToBinary() + { + var fbb = new FlatBufferBuilder(0x10000); + InertialValue.FinishInertialValueBuffer(fbb, InertialValue.Pack(fbb, this)); + return fbb.DataBuffer.ToSizedArray(); + } + } } diff --git a/samples-net/diagnostics.logbook/.vscode/tasks.json b/samples-net/diagnostics.logbook/.vscode/tasks.json index b6886359..a85b39fa 100644 --- a/samples-net/diagnostics.logbook/.vscode/tasks.json +++ b/samples-net/diagnostics.logbook/.vscode/tasks.json @@ -1,55 +1,228 @@ { - "version": "2.0.0", - "tasks": [ - { - "label": "build snap amd64", - "type": "shell", - "command": "bash", - "args": [ - "build-snap-amd64.sh" - ], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build snap arm64", - "type": "shell", - "command": "bash", - "args": [ - "build-snap-arm64.sh" - ], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build project", - "command": "dotnet", - "type": "process", - "args": [ - "build", - "${workspaceFolder}/diagnostics.logbook.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary" - ], - "problemMatcher": "$msCompile" - }, - { - "label": "clean project", - "command": "dotnet", - "type": "process", - "args": [ - "clean", - "${workspaceFolder}/diagnostics.logbook.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary" - ], - "problemMatcher": "$msCompile" - } - ] + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "build project", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/diagnostics.logbook.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "clean project", + "command": "dotnet", + "type": "process", + "args": [ + "clean", + "${workspaceFolder}/diagnostics.logbook.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "Build snap amd64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-amd64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build snap arm64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-arm64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + ], + "inputs": [ + { + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", + "type": "promptString", + "description": "IP address", + "default": "192.168.1.1" + }, + { + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", + "type": "promptString", + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" + }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" + } + ] } \ No newline at end of file diff --git a/samples-net/diagnostics.logbook/Program.cs b/samples-net/diagnostics.logbook/Program.cs index 400c6ac4..0ba5a96f 100644 --- a/samples-net/diagnostics.logbook/Program.cs +++ b/samples-net/diagnostics.logbook/Program.cs @@ -1,7 +1,7 @@ /* MIT License -Copyright (c) 2021-2022 Bosch Rexroth AG +Copyright (c) 2021-2023 Bosch Rexroth AG Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/samples-net/diagnostics.logbook/diagnostics.logbook.csproj b/samples-net/diagnostics.logbook/diagnostics.logbook.csproj index db1ff02e..cb7951b5 100644 --- a/samples-net/diagnostics.logbook/diagnostics.logbook.csproj +++ b/samples-net/diagnostics.logbook/diagnostics.logbook.csproj @@ -8,8 +8,7 @@ - - + diff --git a/samples-net/hello.web.asp/.vscode/tasks.json b/samples-net/hello.web.asp/.vscode/tasks.json index a22ba7c3..94190193 100644 --- a/samples-net/hello.web.asp/.vscode/tasks.json +++ b/samples-net/hello.web.asp/.vscode/tasks.json @@ -1,57 +1,228 @@ { - // See https://go.microsoft.com/fwlink/?LinkId=733558 - // for the documentation about the tasks.json format - "version": "2.0.0", - "tasks": [ - { - "label": "build snap amd64", - "type": "shell", - "command": "bash", - "args": [ - "build-snap-amd64.sh" - ], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build snap arm64", - "type": "shell", - "command": "bash", - "args": [ - "build-snap-arm64.sh" - ], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build project", - "command": "dotnet", - "type": "process", - "args": [ - "build", - "${workspaceFolder}/hello.web.asp.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary" - ], - "problemMatcher": "$msCompile" - }, - { - "label": "clean project", - "command": "dotnet", - "type": "process", - "args": [ - "clean", - "${workspaceFolder}/hello.web.asp.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary" - ], - "problemMatcher": "$msCompile" - } - ] + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "build project", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/hello.web.asp.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "clean project", + "command": "dotnet", + "type": "process", + "args": [ + "clean", + "${workspaceFolder}/hello.web.asp.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "Build snap amd64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-amd64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build snap arm64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-arm64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + ], + "inputs": [ + { + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", + "type": "promptString", + "description": "IP address", + "default": "192.168.1.1" + }, + { + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", + "type": "promptString", + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" + }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" + } + ] } \ No newline at end of file diff --git a/samples-net/hello.web.asp/Program.cs b/samples-net/hello.web.asp/Program.cs index 53cf452a..248fbf38 100644 --- a/samples-net/hello.web.asp/Program.cs +++ b/samples-net/hello.web.asp/Program.cs @@ -22,11 +22,13 @@ public static void Main(string[] args) /// /// The args. /// The . - public static IHostBuilder CreateHostBuilder(string[] args) => - Host.CreateDefaultBuilder(args) + public static IHostBuilder CreateHostBuilder(string[] args) + { + return Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup(); }); + } } } diff --git a/samples-net/hello.web.asp/Startup.cs b/samples-net/hello.web.asp/Startup.cs index a0fef9bb..291ee10e 100644 --- a/samples-net/hello.web.asp/Startup.cs +++ b/samples-net/hello.web.asp/Startup.cs @@ -1,3 +1,26 @@ +/* +MIT License + +Copyright (c) 2021-2023 Bosch Rexroth AG + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ using Hello.Web.Asp.services; namespace Hello.Web.Asp diff --git a/samples-net/hello.web.asp/hello.web.asp.csproj b/samples-net/hello.web.asp/hello.web.asp.csproj index ccf4a465..c1762db0 100644 --- a/samples-net/hello.web.asp/hello.web.asp.csproj +++ b/samples-net/hello.web.asp/hello.web.asp.csproj @@ -7,7 +7,7 @@ - + diff --git a/samples-net/hello.web.asp/services/DataLayerService.cs b/samples-net/hello.web.asp/services/DataLayerService.cs index 181a9b60..7fb919b1 100644 --- a/samples-net/hello.web.asp/services/DataLayerService.cs +++ b/samples-net/hello.web.asp/services/DataLayerService.cs @@ -1,3 +1,26 @@ +/* +MIT License + +Copyright (c) 2021-2023 Bosch Rexroth AG + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ using System.Globalization; namespace Hello.Web.Asp.services @@ -30,7 +53,6 @@ public DataLayerService() /// The . private static IClient CreateClient() { - // Create a new ctrlX Data Layer system var system = new DatalayerSystem(); @@ -38,13 +60,13 @@ private static IClient CreateClient() system.Start(startBroker: false); Console.WriteLine("ctrlX Data Layer system started."); - // Create a connection string with the parameters according to your environment (see Remote class) - var connectionString = new Remote(ip: "192.168.1.1", sslPort: 443).ToString(); + // Create a remote address with the parameters according to your environment + var remote = new Remote(ip: "192.168.1.1", sslPort: 443).ToString(); // Create the client with remote connection string - using var client = system.Factory.CreateClient(connectionString); - Console.WriteLine("ctrlX Data Layer client created."); - + using var client = system.Factory.CreateClient(remote); + Console.WriteLine("ctrlX Data Layer client created."); + return client; } diff --git a/samples-net/hello.web.asp/services/GreetService.cs b/samples-net/hello.web.asp/services/GreetService.cs index 2b6be722..3d3c54d1 100644 --- a/samples-net/hello.web.asp/services/GreetService.cs +++ b/samples-net/hello.web.asp/services/GreetService.cs @@ -1,4 +1,27 @@ -namespace Hello.Web.Asp.services +/* +MIT License + +Copyright (c) 2021-2023 Bosch Rexroth AG + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ +namespace Hello.Web.Asp.services { /// /// Defines the . @@ -23,6 +46,9 @@ public GreetService(string greeting) /// The Say. /// /// The . - public string Say() => Greeting; + public string Say() + { + return Greeting; + } } } diff --git a/samples-net/hello.world/.vscode/tasks.json b/samples-net/hello.world/.vscode/tasks.json index b5497ee2..802d433d 100644 --- a/samples-net/hello.world/.vscode/tasks.json +++ b/samples-net/hello.world/.vscode/tasks.json @@ -1,109 +1,228 @@ { - "version": "2.0.0", - "tasks": [ - { - "label": "build project", - "command": "dotnet", - "type": "process", - "args": [ - "build", - "${workspaceFolder}/hello.world.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary" - ], - "problemMatcher": "$msCompile" - }, - { - "label": "clean project", - "command": "dotnet", - "type": "process", - "args": [ - "clean", - "${workspaceFolder}/hello.world.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary" - ], - "problemMatcher": "$msCompile" - }, - { - "label": "publish amd64", - "command": "dotnet", - "type": "process", - "args": [ - "publish", - "-c", - "Release", - "-r", - "linux-x64", - "-o", - "${workspaceFolder}/publish/amd64", - "--self-contained", - "true", - "${workspaceFolder}/hello.world.csproj", - "/property:GenerateFullPaths=true", - "/property:PublishSingleFile=true", - "/property:PublishTrimmed=true", - "/property:DebugType=None", - "/property:DebugSymbols=false", - "/consoleloggerparameters:NoSummary" - ], - "problemMatcher": "$msCompile" - }, - { - "label": "publish arm64", - "command": "dotnet", - "type": "process", - "args": [ - "publish", - "-c", - "Release", - "-r", - "linux-arm64", - "-o", - "${workspaceFolder}/publish/arm64", - "--self-contained", - "true", - "${workspaceFolder}/hello.world.csproj", - "/property:GenerateFullPaths=true", - "/property:PublishSingleFile=true", - "/property:PublishTrimmed=true", - "/property:DebugType=None", - "/property:DebugSymbols=false", - "/consoleloggerparameters:NoSummary" - ], - "problemMatcher": "$msCompile" - }, - { - "label": "snap amd64", - "group": { - "kind": "build", - "isDefault": true - }, - "type": "shell", - "problemMatcher": [], - "command": "snapcraft clean --destructive-mode && snapcraft --destructive-mode", - "options": { - "cwd": "${workspaceFolder}" - }, - "dependsOn": [ - "publish amd64" - ] - }, - { - "label": "snap arm64", - "group": { - "kind": "build", - "isDefault": true - }, - "type": "shell", - "problemMatcher": [], - "command": "snapcraft clean --destructive-mode && snapcraft --destructive-mode --enable-experimental-target-arch --target-arch arm64", - "options": { - "cwd": "${workspaceFolder}" - }, - "dependsOn": [ - "publish arm64" - ] - } - ] + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "build project", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/hello.world.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "clean project", + "command": "dotnet", + "type": "process", + "args": [ + "clean", + "${workspaceFolder}/hello.world.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "Build snap amd64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-amd64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build snap arm64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-arm64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + ], + "inputs": [ + { + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", + "type": "promptString", + "description": "IP address", + "default": "192.168.1.1" + }, + { + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", + "type": "promptString", + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" + }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" + } + ] } \ No newline at end of file diff --git a/samples-net/hello.world/Program.cs b/samples-net/hello.world/Program.cs index 256d74aa..29a80509 100644 --- a/samples-net/hello.world/Program.cs +++ b/samples-net/hello.world/Program.cs @@ -1,7 +1,7 @@ /* MIT License -Copyright (c) 2021-2022 Bosch Rexroth AG +Copyright (c) 2021-2023 Bosch Rexroth AG Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/samples-net/hello.world/hello.world.csproj b/samples-net/hello.world/hello.world.csproj index c86567f7..999165f7 100644 --- a/samples-net/hello.world/hello.world.csproj +++ b/samples-net/hello.world/hello.world.csproj @@ -6,7 +6,7 @@ Samples.HelloWorld - + diff --git a/samples-node/README.md b/samples-node/README.md index 328b0a3b..9a9f7e9e 100644 --- a/samples-node/README.md +++ b/samples-node/README.md @@ -8,6 +8,7 @@ * [Hello World](./hello-world/README.md) * [ctrlX Data Layer Client](./datalayer.client/README.md) * [ctrlX Data Layer Provider](./datalayer.provider/README.md) +* [ctrlX Solutions WebDAV Interface](./solutions.webdav.interface/README.md) ### Advanced Samples diff --git a/samples-node/datalayer.client.browse/.vscode/tasks.json b/samples-node/datalayer.client.browse/.vscode/tasks.json index 760936ef..32bbc133 100644 --- a/samples-node/datalayer.client.browse/.vscode/tasks.json +++ b/samples-node/datalayer.client.browse/.vscode/tasks.json @@ -1,60 +1,233 @@ { - "version": "2.0.0", - "tasks": [ - { - "label": "build snap amd64", - "type": "shell", - "command": "bash", - "args": [ - "build-snap-amd64.sh" - ], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build snap arm64", - "type": "shell", - "command": "bash", - "args": [ - "build-snap-arm64.sh" - ], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "npm clean", - "group": { - "kind": "build", - "isDefault": true - }, - "type": "shell", - "problemMatcher": [], - "command": "rm -rf node_modules", - "options": { - "cwd": "${workspaceFolder}" - } - }, - { - "label": "npm install", - "group": { - "kind": "build", - "isDefault": true - }, - "type": "shell", - "problemMatcher": [], - "command": "npm install", - "options": { - "cwd": "${workspaceFolder}" - }, - "dependsOn": [ - "npm clean" - ] - }, - ] + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "npm clean", + "group": { + "kind": "build", + "isDefault": true + }, + "type": "shell", + "problemMatcher": [], + "command": "rm -rf node_modules", + "options": { + "cwd": "${workspaceFolder}" + } + }, + { + "label": "npm install", + "group": { + "kind": "build", + "isDefault": true + }, + "type": "shell", + "problemMatcher": [], + "command": "npm install", + "options": { + "cwd": "${workspaceFolder}" + }, + "dependsOn": [ + "npm clean" + ] + }, + { + "label": "Build snap amd64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-amd64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build snap arm64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-arm64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + ], + "inputs": [ + { + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", + "type": "promptString", + "description": "IP address", + "default": "192.168.1.1" + }, + { + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", + "type": "promptString", + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" + }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" + } + ] } \ No newline at end of file diff --git a/samples-node/datalayer.client.browse/package.json b/samples-node/datalayer.client.browse/package.json index 36462a16..26ada5a0 100644 --- a/samples-node/datalayer.client.browse/package.json +++ b/samples-node/datalayer.client.browse/package.json @@ -11,15 +11,15 @@ "dist" ], "devDependencies": { - "@types/node": "^18.8.4", - "@typescript-eslint/parser": "^5.40.0", - "eslint": "^8.25.0", - "typescript": "^4.8.4", - "ts-node": "^10.8.1" + "@types/node": "^18.13.0", + "@typescript-eslint/parser": "^5.52.0", + "eslint": "^8.34.0", + "typescript": "^4.9.5", + "ts-node": "^10.9.1" }, "dependencies": { - "ctrlx-datalayer": "^1.5.0", - "ctrlx-datalayer-flatbuffers": "^1.18.0" + "ctrlx-datalayer": "^1.6.0", + "ctrlx-datalayer-flatbuffers": "^1.20.0" }, "scripts": { "getName": "echo $npm_package_name", diff --git a/samples-node/datalayer.client.browse/snap/snapcraft.yaml b/samples-node/datalayer.client.browse/snap/snapcraft.yaml index 15631ccf..0804f45f 100644 --- a/samples-node/datalayer.client.browse/snap/snapcraft.yaml +++ b/samples-node/datalayer.client.browse/snap/snapcraft.yaml @@ -3,14 +3,14 @@ # Snapcraft references # See https://snapcraft.io/docs/snapcraft-yaml-reference name: ctrlx-node-datalayer-client-browse -version: '1.0.0' +version: "1.0.0" summary: Data Layer browse sample written in Node.js for ctrlX. description: | The sample app shows how to browse the Data Layer tree. -confinement: strict -#confinement: devmode +confinement: strict +#confinement: devmode #icon: assets/icons/ICONHERE.png -grade: stable # must be 'stable' to release into candidate/stable channels +grade: stable # must be 'stable' to release into candidate/stable channels base: core20 type: app @@ -28,13 +28,13 @@ parts: app: source: . build-environment: - # Set the node version here. We recommend to use the latest LTS version. - - NODE_VERSION: "16.15.1" - + # Set the node version here. We recommend to use the latest LTS version. + - NODE_VERSION: "18.15.0" + # We don't use the npm plugin here, because it has no X-build capability (can't build arm64 target snaps on amd64). # plugin: npm - # npm-node-version: "16.15.1" - plugin: nil + # npm-node-version: "18.15.0" + plugin: nil override-build: | # set target arch if [ $SNAPCRAFT_TARGET_ARCH == "arm64" ]; then @@ -50,15 +50,12 @@ parts: if [ ! -f "${SNAPCRAFT_PART_INSTALL}/bin/node" ]; then curl $node_uri | tar xzf - -C $SNAPCRAFT_PART_INSTALL/ --no-same-owner --strip-components=1 fi - - # setup npm - npm config set unsafe-perm true - + # install the app (full) to compile (tsc -> ./dist) - npm install + npm install --unsafe-perm # pack and install the app (only production) - npm install -g --prefix $SNAPCRAFT_PART_INSTALL $(npm pack . | tail -1) --only=prod --production --no-fund + npm install -g --prefix $SNAPCRAFT_PART_INSTALL $(npm pack . | tail -1) --only=prod --production --no-fund --unsafe-perm # remove ctrlx-datalayer prebuilds of unused archs to reduce snap size package_name=$(npm run getName -s) @@ -74,4 +71,4 @@ plugs: datalayer: interface: content content: datalayer - target: $SNAP_DATA/.datalayer \ No newline at end of file + target: $SNAP_DATA/.datalayer diff --git a/samples-node/datalayer.client.browse/src/app.ts b/samples-node/datalayer.client.browse/src/app.ts index af34eb0d..f5bdecd4 100644 --- a/samples-node/datalayer.client.browse/src/app.ts +++ b/samples-node/datalayer.client.browse/src/app.ts @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2022 Bosch Rexroth AG +// Copyright (c) 2021-2023 Bosch Rexroth AG // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the 'Software'), to deal @@ -19,27 +19,25 @@ // SOFTWARE. import DatalayerSystem from 'ctrlx-datalayer/dist/datalayersystem'; -import DatalayerHelper from './datalayerhelper'; +import { Remote } from 'ctrlx-datalayer/dist/remote'; import Browser from './browser'; // The main function async function main() { - - // Create a new ctrlX Data Layer system const system = new DatalayerSystem(''); // Starts the ctrlX Data Layer system without a new broker (startBroker = false) because one broker is already running on ctrlX device await system.start(false); - // Create a connection string with the parameters according to your environment (see DatalayerHelper class) - const connectionString = DatalayerHelper.getConnectionString({ ip: "192.168.1.1", sslPort: 443 }) - console.log('connection string:', connectionString) + // Create a remote address with the parameters according to your environment + const remote = Remote.build({ ip: "192.168.1.1", sslPort: 443 }) + console.log('connection string:', remote) // Create the client with the given remote address - const client = await system.createClient(connectionString); + const client = await system.createClient(remote); // Check if client is connected. if (client.isConnected() === false) { diff --git a/samples-node/datalayer.client.browse/src/browser.ts b/samples-node/datalayer.client.browse/src/browser.ts index c94ad440..2f0ae519 100644 --- a/samples-node/datalayer.client.browse/src/browser.ts +++ b/samples-node/datalayer.client.browse/src/browser.ts @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2022 Bosch Rexroth AG +// Copyright (c) 2021-2023 Bosch Rexroth AG // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the 'Software'), to deal @@ -44,9 +44,9 @@ class Browser { try { const variant = await this.client.browse(address); const children = variant.value as Array; - for (var i = 0; i < children.length; i++) { + for (let i = 0; i < children.length; i++) { const childAddress = address === '' ? children[i] : `${address}/${children[i]}`; - await this.traverse(childAddress, children[i], indent, i == children.length - 1); + await this.traverse(childAddress, children[i], indent, i === children.length - 1); } } catch (error) { // do nothing in case of error diff --git a/samples-node/datalayer.client.browse/src/datalayerhelper.ts b/samples-node/datalayer.client.browse/src/datalayerhelper.ts deleted file mode 100644 index 47f1c61c..00000000 --- a/samples-node/datalayer.client.browse/src/datalayerhelper.ts +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) 2021-2022 Bosch Rexroth AG - -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the 'Software'), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -/** -* This class provides auxiliary methods to create ctrlX Datalayer client and provider connection strings to ctrlX CORE devices. -* It can be used for both running in an app build environment(QEMU VM) and within the snap environment on the ctrlX CORE. -* -* Feel free to use it in your projects and to change it if necessary. -* -* For ease of use, the default values for IP address, user, password and SSL port are chosen to match the settings of a -* newly created ctrlX CORE device: -* -* ip="192.168.1.1" -* user="boschrexroth" -* password="boschrexroth" -* sslPort=443 -* -* with these variables, the tcp connection string can be formatted as follows: -* -* tcp://{user}:{password}@{ip}?sslport={sslPort} -* -* If these values do not suit your use case, explicitly pass the parameters that require different values. -* -* Here some examples: -* -* 1. ctrlX CORE or ctrlX CORE virtual with another IP address, user and password: -* -* const connectionString = DatalayerHelper.getConnectionString({ ip: "192.168.1.100", user: "admin", password: "-$_U/{X$aG}Z3/e<" }) -* -* 2. ctrlX CORE virtual with port forwarding running on the same host as the app build environment (QEMU VM): -* -* const connectionString = DatalayerHelper.getConnectionString({ ip: "10.0.2.2", sslPort: 8443 }) -* -* Remarks: -* 10.0.2.2 is the IP address of the host from the point of view of the app build environment(QEMU VM). -* 8443 is the host port which is forwarded to the SSL port(=433) of the ctrlX CORE virtual -* -* 3. ctrlX CORE virtual with port forwarding running on windows build environment (MS Visual Studio): -* -* const connectionString = DatalayerHelper.getConnectionString({ ip: "127.0.0.1", sslPort: 8443 }) -* -* Remarks: -* 127.0.0.1 is the IP address of the ctrlX virtual on the windows host system. -* 8443 is the host port which is forwarded to the SSL port(=433) of the ctrlX CORE virtual -* -* IMPORTANT: -* You need not change the parameter settings before building a snap and installing the snap on a ctrlX CORE. -* The method detects the snap environment and uses automatically inter process communication. -* Therefor the connection string to the ctrlX Datalayer is: "ipc://" -*/ -class DatalayerHelper { - - /** - * Combines a ctrlX Datalayer connection string. - * @param ip: IP address of the ctrlX CORE. Use "10.0.2.2" to connect to a ctrlX CORE virtual with port forwarding - * @param user: Name of the user - * @param password: Password of the user - * @param sslPort: Port number for a SSL connection. ctrlX CORE virtual with port forwarding: Use the host port (default 8443) forwarded to port 22 of the ctrlX virtual - * @returns The connection string: ipc connection string if running inside snap otherwise tcp connection string - */ - public static getConnectionString({ ip = "192.168.1.1", user = "boschrexroth", password = "boschrexroth", sslPort = 443 }: { ip?: string, user?: string, password?: string, sslPort?: Number }): string { - if (typeof process.env.SNAP_NAME !== 'undefined' && process.env.SNAP_NAME !== 'node') { - return "ipc://"; - } - - return 'tcp://' + user + ':' + password + '@' + ip + '?sslport=' + sslPort; - } -} - -export = DatalayerHelper; \ No newline at end of file diff --git a/samples-node/datalayer.client.bulkread/.vscode/tasks.json b/samples-node/datalayer.client.bulkread/.vscode/tasks.json index f728dad1..43749bb0 100644 --- a/samples-node/datalayer.client.bulkread/.vscode/tasks.json +++ b/samples-node/datalayer.client.bulkread/.vscode/tasks.json @@ -1,60 +1,233 @@ { - "version": "2.0.0", - "tasks": [ - { - "label": "build snap amd64", - "type": "shell", - "command": "bash", - "args": [ - "build-snap-amd64.sh" - ], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build snap arm64", - "type": "shell", - "command": "bash", - "args": [ - "build-snap-arm64.sh" - ], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "npm clean", - "group": { - "kind": "build", - "isDefault": true - }, - "type": "shell", - "problemMatcher": [], - "command": "rm -rf node_modules", - "options": { - "cwd": "${workspaceFolder}" - } - }, - { - "label": "npm install", - "group": { - "kind": "build", - "isDefault": true - }, - "type": "shell", - "problemMatcher": [], - "command": "npm install", - "options": { - "cwd": "${workspaceFolder}" - }, - "dependsOn": [ - "npm clean" - ] - }, - ] + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "npm clean", + "group": { + "kind": "build", + "isDefault": true + }, + "type": "shell", + "problemMatcher": [], + "command": "rm -rf node_modules", + "options": { + "cwd": "${workspaceFolder}" + } + }, + { + "label": "npm install", + "group": { + "kind": "build", + "isDefault": true + }, + "type": "shell", + "problemMatcher": [], + "command": "npm install", + "options": { + "cwd": "${workspaceFolder}" + }, + "dependsOn": [ + "npm clean" + ] + }, + { + "label": "Build snap amd64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-amd64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build snap arm64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-arm64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + ], + "inputs": [ + { + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", + "type": "promptString", + "description": "IP address", + "default": "192.168.1.1" + }, + { + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", + "type": "promptString", + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" + }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" + } + ] } \ No newline at end of file diff --git a/samples-node/datalayer.client.bulkread/package.json b/samples-node/datalayer.client.bulkread/package.json index 855d031c..5aacff7e 100644 --- a/samples-node/datalayer.client.bulkread/package.json +++ b/samples-node/datalayer.client.bulkread/package.json @@ -11,15 +11,15 @@ "dist" ], "devDependencies": { - "@types/node": "^18.8.4", - "@typescript-eslint/parser": "^5.40.0", - "eslint": "^8.25.0", - "typescript": "^4.8.4", - "ts-node": "^10.8.1" + "@types/node": "^18.13.0", + "@typescript-eslint/parser": "^5.52.0", + "eslint": "^8.34.0", + "typescript": "^4.9.5", + "ts-node": "^10.9.1" }, "dependencies": { - "ctrlx-datalayer": "^1.4.1", - "ctrlx-datalayer-flatbuffers": "^1.18.0" + "ctrlx-datalayer": "^1.6.0", + "ctrlx-datalayer-flatbuffers": "^1.20.0" }, "scripts": { "getName": "echo $npm_package_name", diff --git a/samples-node/datalayer.client.bulkread/snap/snapcraft.yaml b/samples-node/datalayer.client.bulkread/snap/snapcraft.yaml index 17fddbef..0330d4e4 100644 --- a/samples-node/datalayer.client.bulkread/snap/snapcraft.yaml +++ b/samples-node/datalayer.client.bulkread/snap/snapcraft.yaml @@ -3,15 +3,15 @@ # Snapcraft references # See https://snapcraft.io/docs/snapcraft-yaml-reference name: ctrlx-node-datalayer-client-bulkread -version: '1.0.0' +version: "1.0.0" summary: Data Layer client bulk read sample written in node.js for ctrlX. description: | The sample demonstrates how to bulk read values from ctrlX Data Layer tree and write out the values to console. The bulk read is performed synchron and asynchron every 10 seconds in an endless loop. -confinement: strict -#confinement: devmode +confinement: strict +#confinement: devmode #icon: assets/icons/ICONHERE.png -grade: stable # must be 'stable' to release into candidate/stable channels +grade: stable # must be 'stable' to release into candidate/stable channels base: core20 type: app @@ -29,13 +29,13 @@ parts: app: source: . build-environment: - # Set the node version here. We recommend to use the latest LTS version. - - NODE_VERSION: "16.15.1" - + # Set the node version here. We recommend to use the latest LTS version. + - NODE_VERSION: "18.15.0" + # We don't use the npm plugin here, because it has no X-build capability (can't build arm64 target snaps on amd64). # plugin: npm - # npm-node-version: "16.15.1" - plugin: nil + # npm-node-version: "18.15.0" + plugin: nil override-build: | # set target arch if [ $SNAPCRAFT_TARGET_ARCH == "arm64" ]; then @@ -51,15 +51,12 @@ parts: if [ ! -f "${SNAPCRAFT_PART_INSTALL}/bin/node" ]; then curl $node_uri | tar xzf - -C $SNAPCRAFT_PART_INSTALL/ --no-same-owner --strip-components=1 fi - - # setup npm - npm config set unsafe-perm true - + # install the app (full) to compile (tsc -> ./dist) - npm install + npm install --unsafe-perm # pack and install the app (only production) - npm install -g --prefix $SNAPCRAFT_PART_INSTALL $(npm pack . | tail -1) --only=prod --production --no-fund + npm install -g --prefix $SNAPCRAFT_PART_INSTALL $(npm pack . | tail -1) --only=prod --production --no-fund --unsafe-perm # remove ctrlx-datalayer prebuilds of unused archs to reduce snap size package_name=$(npm run getName -s) @@ -75,4 +72,4 @@ plugs: datalayer: interface: content content: datalayer - target: $SNAP_DATA/.datalayer \ No newline at end of file + target: $SNAP_DATA/.datalayer diff --git a/samples-node/datalayer.client.bulkread/src/app.ts b/samples-node/datalayer.client.bulkread/src/app.ts index 743b16d9..59ac308f 100644 --- a/samples-node/datalayer.client.bulkread/src/app.ts +++ b/samples-node/datalayer.client.bulkread/src/app.ts @@ -1,7 +1,7 @@ #!/usr/bin/env node // !!! DO NOT REMOVE THE SHEBANG ON TOP OF THE FILE, WHICH SPECIFIES THIS APP TO BE EXECUTED BY NODE.JS !!! -// Copyright (c) 2021-2022 Bosch Rexroth AG +// Copyright (c) 2021-2023 Bosch Rexroth AG // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the 'Software'), to deal @@ -22,7 +22,7 @@ // SOFTWARE. import DatalayerSystem from 'ctrlx-datalayer/dist/datalayersystem'; -import DatalayerHelper from './datalayerhelper'; +import { Remote } from 'ctrlx-datalayer/dist/remote'; // The main function async function main() { @@ -33,12 +33,12 @@ async function main() { // Starts the ctrlX Data Layer system without a new broker (startBroker = false) because one broker is already running on ctrlX device await system.start(false); - // Create a connection string with the parameters according to your environment (see DatalayerHelper class) - const connectionString = DatalayerHelper.getConnectionString({ ip: "10.0.2.2", sslPort: 8443 }) - console.log('connection string:', connectionString) + // Create a remote address with the parameters according to your environment + const remote = Remote.build({ ip: "10.0.2.2", sslPort: 8443 }) + console.log('connection string:', remote) // Create the client with the given remote address - const client = await system.createClient(connectionString); + const client = await system.createClient(remote); if (client.isConnected() === false) { console.log('client is not connected -> exit.') diff --git a/samples-node/datalayer.client.bulkread/src/datalayerhelper.ts b/samples-node/datalayer.client.bulkread/src/datalayerhelper.ts deleted file mode 100644 index 47f1c61c..00000000 --- a/samples-node/datalayer.client.bulkread/src/datalayerhelper.ts +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) 2021-2022 Bosch Rexroth AG - -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the 'Software'), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -/** -* This class provides auxiliary methods to create ctrlX Datalayer client and provider connection strings to ctrlX CORE devices. -* It can be used for both running in an app build environment(QEMU VM) and within the snap environment on the ctrlX CORE. -* -* Feel free to use it in your projects and to change it if necessary. -* -* For ease of use, the default values for IP address, user, password and SSL port are chosen to match the settings of a -* newly created ctrlX CORE device: -* -* ip="192.168.1.1" -* user="boschrexroth" -* password="boschrexroth" -* sslPort=443 -* -* with these variables, the tcp connection string can be formatted as follows: -* -* tcp://{user}:{password}@{ip}?sslport={sslPort} -* -* If these values do not suit your use case, explicitly pass the parameters that require different values. -* -* Here some examples: -* -* 1. ctrlX CORE or ctrlX CORE virtual with another IP address, user and password: -* -* const connectionString = DatalayerHelper.getConnectionString({ ip: "192.168.1.100", user: "admin", password: "-$_U/{X$aG}Z3/e<" }) -* -* 2. ctrlX CORE virtual with port forwarding running on the same host as the app build environment (QEMU VM): -* -* const connectionString = DatalayerHelper.getConnectionString({ ip: "10.0.2.2", sslPort: 8443 }) -* -* Remarks: -* 10.0.2.2 is the IP address of the host from the point of view of the app build environment(QEMU VM). -* 8443 is the host port which is forwarded to the SSL port(=433) of the ctrlX CORE virtual -* -* 3. ctrlX CORE virtual with port forwarding running on windows build environment (MS Visual Studio): -* -* const connectionString = DatalayerHelper.getConnectionString({ ip: "127.0.0.1", sslPort: 8443 }) -* -* Remarks: -* 127.0.0.1 is the IP address of the ctrlX virtual on the windows host system. -* 8443 is the host port which is forwarded to the SSL port(=433) of the ctrlX CORE virtual -* -* IMPORTANT: -* You need not change the parameter settings before building a snap and installing the snap on a ctrlX CORE. -* The method detects the snap environment and uses automatically inter process communication. -* Therefor the connection string to the ctrlX Datalayer is: "ipc://" -*/ -class DatalayerHelper { - - /** - * Combines a ctrlX Datalayer connection string. - * @param ip: IP address of the ctrlX CORE. Use "10.0.2.2" to connect to a ctrlX CORE virtual with port forwarding - * @param user: Name of the user - * @param password: Password of the user - * @param sslPort: Port number for a SSL connection. ctrlX CORE virtual with port forwarding: Use the host port (default 8443) forwarded to port 22 of the ctrlX virtual - * @returns The connection string: ipc connection string if running inside snap otherwise tcp connection string - */ - public static getConnectionString({ ip = "192.168.1.1", user = "boschrexroth", password = "boschrexroth", sslPort = 443 }: { ip?: string, user?: string, password?: string, sslPort?: Number }): string { - if (typeof process.env.SNAP_NAME !== 'undefined' && process.env.SNAP_NAME !== 'node') { - return "ipc://"; - } - - return 'tcp://' + user + ':' + password + '@' + ip + '?sslport=' + sslPort; - } -} - -export = DatalayerHelper; \ No newline at end of file diff --git a/samples-node/datalayer.client/.vscode/tasks.json b/samples-node/datalayer.client/.vscode/tasks.json index 760936ef..32bbc133 100644 --- a/samples-node/datalayer.client/.vscode/tasks.json +++ b/samples-node/datalayer.client/.vscode/tasks.json @@ -1,60 +1,233 @@ { - "version": "2.0.0", - "tasks": [ - { - "label": "build snap amd64", - "type": "shell", - "command": "bash", - "args": [ - "build-snap-amd64.sh" - ], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build snap arm64", - "type": "shell", - "command": "bash", - "args": [ - "build-snap-arm64.sh" - ], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "npm clean", - "group": { - "kind": "build", - "isDefault": true - }, - "type": "shell", - "problemMatcher": [], - "command": "rm -rf node_modules", - "options": { - "cwd": "${workspaceFolder}" - } - }, - { - "label": "npm install", - "group": { - "kind": "build", - "isDefault": true - }, - "type": "shell", - "problemMatcher": [], - "command": "npm install", - "options": { - "cwd": "${workspaceFolder}" - }, - "dependsOn": [ - "npm clean" - ] - }, - ] + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "npm clean", + "group": { + "kind": "build", + "isDefault": true + }, + "type": "shell", + "problemMatcher": [], + "command": "rm -rf node_modules", + "options": { + "cwd": "${workspaceFolder}" + } + }, + { + "label": "npm install", + "group": { + "kind": "build", + "isDefault": true + }, + "type": "shell", + "problemMatcher": [], + "command": "npm install", + "options": { + "cwd": "${workspaceFolder}" + }, + "dependsOn": [ + "npm clean" + ] + }, + { + "label": "Build snap amd64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-amd64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build snap arm64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-arm64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + ], + "inputs": [ + { + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", + "type": "promptString", + "description": "IP address", + "default": "192.168.1.1" + }, + { + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", + "type": "promptString", + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" + }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" + } + ] } \ No newline at end of file diff --git a/samples-node/datalayer.client/package.json b/samples-node/datalayer.client/package.json index 70df89d9..770918b0 100644 --- a/samples-node/datalayer.client/package.json +++ b/samples-node/datalayer.client/package.json @@ -11,15 +11,15 @@ "dist" ], "devDependencies": { - "@types/node": "^18.8.4", - "@typescript-eslint/parser": "^5.40.0", - "eslint": "^8.25.0", - "typescript": "^4.8.4", - "ts-node": "^10.8.1" + "@types/node": "^18.13.0", + "@typescript-eslint/parser": "^5.52.0", + "eslint": "^8.34.0", + "typescript": "^4.9.5", + "ts-node": "^10.9.1" }, "dependencies": { - "ctrlx-datalayer": "^1.5.0", - "ctrlx-datalayer-flatbuffers": "^1.18.0" + "ctrlx-datalayer": "^1.6.0", + "ctrlx-datalayer-flatbuffers": "^1.20.0" }, "scripts": { "getName": "echo $npm_package_name", diff --git a/samples-node/datalayer.client/snap/snapcraft.yaml b/samples-node/datalayer.client/snap/snapcraft.yaml index aab6571b..bac5d799 100644 --- a/samples-node/datalayer.client/snap/snapcraft.yaml +++ b/samples-node/datalayer.client/snap/snapcraft.yaml @@ -3,16 +3,16 @@ # Snapcraft references # See https://snapcraft.io/docs/snapcraft-yaml-reference name: ctrlx-node-datalayer-client -version: '1.0.0' +version: "1.0.0" summary: Data Layer client sample written in Node.js for ctrlX. description: | The sample demonstrates how to read values from ctrlX Data Layer tree and write out the values to console. A subscription is used to get values by data change event in a deterministic publish interval. The single read is performed every 10 seconds in an endless loop. -confinement: strict -#confinement: devmode +confinement: strict +#confinement: devmode #icon: assets/icons/ICONHERE.png -grade: stable # must be 'stable' to release into candidate/stable channels +grade: stable # must be 'stable' to release into candidate/stable channels base: core20 type: app @@ -30,13 +30,13 @@ parts: app: source: . build-environment: - # Set the node version here. We recommend to use the latest LTS version. - - NODE_VERSION: "16.15.1" - + # Set the node version here. We recommend to use the latest LTS version. + - NODE_VERSION: "18.15.0" + # We don't use the npm plugin here, because it has no X-build capability (can't build arm64 target snaps on amd64). # plugin: npm - # npm-node-version: "16.15.1" - plugin: nil + # npm-node-version: "18.15.0" + plugin: nil override-build: | # set target arch if [ $SNAPCRAFT_TARGET_ARCH == "arm64" ]; then @@ -53,14 +53,11 @@ parts: curl $node_uri | tar xzf - -C $SNAPCRAFT_PART_INSTALL/ --no-same-owner --strip-components=1 fi - # setup npm - npm config set unsafe-perm true - # install the app (full) to compile (tsc -> ./dist) - npm install + npm install --unsafe-perm # pack and install the app (only production) - npm install -g --prefix $SNAPCRAFT_PART_INSTALL $(npm pack . | tail -1) --only=prod --production --no-fund + npm install -g --prefix $SNAPCRAFT_PART_INSTALL $(npm pack . | tail -1) --only=prod --production --no-fund --unsafe-perm # remove ctrlx-datalayer prebuilds of unused archs to reduce snap size package_name=$(npm run getName -s) @@ -76,4 +73,4 @@ plugs: datalayer: interface: content content: datalayer - target: $SNAP_DATA/.datalayer \ No newline at end of file + target: $SNAP_DATA/.datalayer diff --git a/samples-node/datalayer.client/src/app.ts b/samples-node/datalayer.client/src/app.ts index 5f258c7f..6bb86fa8 100644 --- a/samples-node/datalayer.client/src/app.ts +++ b/samples-node/datalayer.client/src/app.ts @@ -1,7 +1,7 @@ #!/usr/bin/env node // !!! DO NOT REMOVE THE SHEBANG ON TOP OF THE FILE, WHICH SPECIFIES THIS APP TO BE EXECUTED BY NODE.JS !!! -// Copyright (c) 2021-2022 Bosch Rexroth AG +// Copyright (c) 2021-2023 Bosch Rexroth AG // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the 'Software'), to deal @@ -26,7 +26,7 @@ import INotifyItem from 'ctrlx-datalayer/dist/notifyitem'; import IResult from 'ctrlx-datalayer/dist/result'; import * as SubscriptionUtils from 'ctrlx-datalayer/dist/subscription-utils'; -import DatalayerHelper from './datalayerhelper'; +import { Remote } from 'ctrlx-datalayer/dist/remote'; // The main function async function main() { @@ -37,12 +37,12 @@ async function main() { // Starts the ctrlX Data Layer system without a new broker (startBroker = false) because one broker is already running on ctrlX device await system.start(false); - // Create a connection string with the parameters according to your environment (see DatalayerHelper class) - const connectionString = DatalayerHelper.getConnectionString({ ip: "192.168.1.1", sslPort: 443 }) - console.log('connection string:', connectionString) + // Create a remote address with the parameters according to your environment + const remote = Remote.build({ ip: "192.168.1.1", sslPort: 443 }) + console.log('connection string:', remote) // Create the client with the given remote address - const client = await system.createClient(connectionString); + const client = await system.createClient(remote); if (client.isConnected() === false) { console.log('client is not connected -> exit.') diff --git a/samples-node/datalayer.client/src/datalayerhelper.ts b/samples-node/datalayer.client/src/datalayerhelper.ts deleted file mode 100644 index 47f1c61c..00000000 --- a/samples-node/datalayer.client/src/datalayerhelper.ts +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) 2021-2022 Bosch Rexroth AG - -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the 'Software'), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -/** -* This class provides auxiliary methods to create ctrlX Datalayer client and provider connection strings to ctrlX CORE devices. -* It can be used for both running in an app build environment(QEMU VM) and within the snap environment on the ctrlX CORE. -* -* Feel free to use it in your projects and to change it if necessary. -* -* For ease of use, the default values for IP address, user, password and SSL port are chosen to match the settings of a -* newly created ctrlX CORE device: -* -* ip="192.168.1.1" -* user="boschrexroth" -* password="boschrexroth" -* sslPort=443 -* -* with these variables, the tcp connection string can be formatted as follows: -* -* tcp://{user}:{password}@{ip}?sslport={sslPort} -* -* If these values do not suit your use case, explicitly pass the parameters that require different values. -* -* Here some examples: -* -* 1. ctrlX CORE or ctrlX CORE virtual with another IP address, user and password: -* -* const connectionString = DatalayerHelper.getConnectionString({ ip: "192.168.1.100", user: "admin", password: "-$_U/{X$aG}Z3/e<" }) -* -* 2. ctrlX CORE virtual with port forwarding running on the same host as the app build environment (QEMU VM): -* -* const connectionString = DatalayerHelper.getConnectionString({ ip: "10.0.2.2", sslPort: 8443 }) -* -* Remarks: -* 10.0.2.2 is the IP address of the host from the point of view of the app build environment(QEMU VM). -* 8443 is the host port which is forwarded to the SSL port(=433) of the ctrlX CORE virtual -* -* 3. ctrlX CORE virtual with port forwarding running on windows build environment (MS Visual Studio): -* -* const connectionString = DatalayerHelper.getConnectionString({ ip: "127.0.0.1", sslPort: 8443 }) -* -* Remarks: -* 127.0.0.1 is the IP address of the ctrlX virtual on the windows host system. -* 8443 is the host port which is forwarded to the SSL port(=433) of the ctrlX CORE virtual -* -* IMPORTANT: -* You need not change the parameter settings before building a snap and installing the snap on a ctrlX CORE. -* The method detects the snap environment and uses automatically inter process communication. -* Therefor the connection string to the ctrlX Datalayer is: "ipc://" -*/ -class DatalayerHelper { - - /** - * Combines a ctrlX Datalayer connection string. - * @param ip: IP address of the ctrlX CORE. Use "10.0.2.2" to connect to a ctrlX CORE virtual with port forwarding - * @param user: Name of the user - * @param password: Password of the user - * @param sslPort: Port number for a SSL connection. ctrlX CORE virtual with port forwarding: Use the host port (default 8443) forwarded to port 22 of the ctrlX virtual - * @returns The connection string: ipc connection string if running inside snap otherwise tcp connection string - */ - public static getConnectionString({ ip = "192.168.1.1", user = "boschrexroth", password = "boschrexroth", sslPort = 443 }: { ip?: string, user?: string, password?: string, sslPort?: Number }): string { - if (typeof process.env.SNAP_NAME !== 'undefined' && process.env.SNAP_NAME !== 'node') { - return "ipc://"; - } - - return 'tcp://' + user + ':' + password + '@' + ip + '?sslport=' + sslPort; - } -} - -export = DatalayerHelper; \ No newline at end of file diff --git a/samples-node/datalayer.provider.alldata/.vscode/tasks.json b/samples-node/datalayer.provider.alldata/.vscode/tasks.json index 760936ef..32bbc133 100644 --- a/samples-node/datalayer.provider.alldata/.vscode/tasks.json +++ b/samples-node/datalayer.provider.alldata/.vscode/tasks.json @@ -1,60 +1,233 @@ { - "version": "2.0.0", - "tasks": [ - { - "label": "build snap amd64", - "type": "shell", - "command": "bash", - "args": [ - "build-snap-amd64.sh" - ], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build snap arm64", - "type": "shell", - "command": "bash", - "args": [ - "build-snap-arm64.sh" - ], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "npm clean", - "group": { - "kind": "build", - "isDefault": true - }, - "type": "shell", - "problemMatcher": [], - "command": "rm -rf node_modules", - "options": { - "cwd": "${workspaceFolder}" - } - }, - { - "label": "npm install", - "group": { - "kind": "build", - "isDefault": true - }, - "type": "shell", - "problemMatcher": [], - "command": "npm install", - "options": { - "cwd": "${workspaceFolder}" - }, - "dependsOn": [ - "npm clean" - ] - }, - ] + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "npm clean", + "group": { + "kind": "build", + "isDefault": true + }, + "type": "shell", + "problemMatcher": [], + "command": "rm -rf node_modules", + "options": { + "cwd": "${workspaceFolder}" + } + }, + { + "label": "npm install", + "group": { + "kind": "build", + "isDefault": true + }, + "type": "shell", + "problemMatcher": [], + "command": "npm install", + "options": { + "cwd": "${workspaceFolder}" + }, + "dependsOn": [ + "npm clean" + ] + }, + { + "label": "Build snap amd64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-amd64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build snap arm64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-arm64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + ], + "inputs": [ + { + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", + "type": "promptString", + "description": "IP address", + "default": "192.168.1.1" + }, + { + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", + "type": "promptString", + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" + }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" + } + ] } \ No newline at end of file diff --git a/samples-node/datalayer.provider.alldata/package.json b/samples-node/datalayer.provider.alldata/package.json index c924cf8a..d0f009fa 100644 --- a/samples-node/datalayer.provider.alldata/package.json +++ b/samples-node/datalayer.provider.alldata/package.json @@ -11,15 +11,15 @@ "dist" ], "devDependencies": { - "@types/node": "^18.8.4", - "@typescript-eslint/parser": "^5.40.0", - "eslint": "^8.25.0", - "typescript": "^4.8.4", - "ts-node": "^10.8.1" + "@types/node": "^18.13.0", + "@typescript-eslint/parser": "^5.52.0", + "eslint": "^8.34.0", + "typescript": "^4.9.5", + "ts-node": "^10.9.1" }, "dependencies": { - "ctrlx-datalayer": "^1.5.0", - "ctrlx-datalayer-flatbuffers": "^1.18.0" + "ctrlx-datalayer": "^1.6.0", + "ctrlx-datalayer-flatbuffers": "^1.20.0" }, "scripts": { "getName": "echo $npm_package_name", diff --git a/samples-node/datalayer.provider.alldata/snap/snapcraft.yaml b/samples-node/datalayer.provider.alldata/snap/snapcraft.yaml index a475746c..d1496f96 100644 --- a/samples-node/datalayer.provider.alldata/snap/snapcraft.yaml +++ b/samples-node/datalayer.provider.alldata/snap/snapcraft.yaml @@ -3,17 +3,17 @@ # Snapcraft references # See https://snapcraft.io/docs/snapcraft-yaml-reference name: ctrlx-node-datalayer-provider-alldata -version: '1.0.0' +version: "1.0.0" summary: Data Layer provider all data sample written in Node.js for ctrlX. description: | The sample demonstrates how to provide all available data types to the ctrlX Data Layer. The demo creates a 'static' and a 'dynamic' folder under the root node 'samples'. The 'static' folder provides nodes with constant values. In the 'dynamic' folder the same nodes are provided as in 'static' folder but with changing value every second. -confinement: strict -#confinement: devmode +confinement: strict +#confinement: devmode #icon: assets/icons/ICONHERE.png -grade: stable # must be 'stable' to release into candidate/stable channels +grade: stable # must be 'stable' to release into candidate/stable channels base: core20 type: app @@ -31,13 +31,13 @@ parts: app: source: . build-environment: - # Set the node version here. We recommend to use the latest LTS version. - - NODE_VERSION: "16.15.1" - + # Set the node version here. We recommend to use the latest LTS version. + - NODE_VERSION: "18.15.0" + # We don't use the npm plugin here, because it has no X-build capability (can't build arm64 target snaps on amd64). # plugin: npm - # npm-node-version: "16.15.1" - plugin: nil + # npm-node-version: "18.15.0" + plugin: nil override-build: | # set target arch if [ $SNAPCRAFT_TARGET_ARCH == "arm64" ]; then @@ -54,14 +54,11 @@ parts: curl $node_uri | tar xzf - -C $SNAPCRAFT_PART_INSTALL/ --no-same-owner --strip-components=1 fi - # setup npm - npm config set unsafe-perm true - # install the app (full) to compile (tsc -> ./dist) - npm install + npm install --unsafe-perm # pack and install the app (only production) - npm install -g --prefix $SNAPCRAFT_PART_INSTALL $(npm pack . | tail -1) --only=prod --production --no-fund + npm install -g --prefix $SNAPCRAFT_PART_INSTALL $(npm pack . | tail -1) --only=prod --production --no-fund --unsafe-perm # remove ctrlx-datalayer prebuilds of unused archs to reduce snap size package_name=$(npm run getName -s) @@ -77,4 +74,4 @@ plugs: datalayer: interface: content content: datalayer - target: $SNAP_DATA/.datalayer \ No newline at end of file + target: $SNAP_DATA/.datalayer diff --git a/samples-node/datalayer.provider.alldata/src/app.ts b/samples-node/datalayer.provider.alldata/src/app.ts index cadcd152..267c91fa 100644 --- a/samples-node/datalayer.provider.alldata/src/app.ts +++ b/samples-node/datalayer.provider.alldata/src/app.ts @@ -1,7 +1,7 @@ #!/usr/bin/env node // !!! DO NOT REMOVE THE SHEBANG ON TOP OF THE FILE, WHICH SPECIFIES THIS APP TO BE EXECUTED BY NODE.JS !!! -// Copyright (c) 2021-2022 Bosch Rexroth AG +// Copyright (c) 2021-2023 Bosch Rexroth AG // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the 'Software'), to deal @@ -32,11 +32,12 @@ import IProviderNodeResult from 'ctrlx-datalayer/dist/providernoderesult'; import * as flatbuffers from 'flatbuffers'; import { InertialValue } from './sample/schema/inertial-value'; -import DataRanges from './dataranges'; -import DataTypes from './datatypes'; +import DATA_RANGES from './dataranges'; +import DATA_TYPES from './datatypes'; import Node from './node'; -import DatalayerHelper from './datalayerhelper'; +// Utils +import { Remote } from 'ctrlx-datalayer/dist/remote'; // The main function async function main() { @@ -48,12 +49,12 @@ async function main() { // Starts the ctrlX Data Layer system without a new broker (startBroker = false) because one broker is already running on ctrlX device await system.start(false); - // Create a connection string with the parameters according to your environment (see DatalayerHelper class) - const connectionString = DatalayerHelper.getConnectionString({ ip: "192.168.1.1", sslPort: 443 }) - console.log('connection string:', connectionString) + // Create a remote address with the parameters according to your environment + const remote = Remote.build({ ip: "192.168.1.1", sslPort: 443 }) + console.log('connection string:', remote) //Create a Provider with the given remote address - const provider = await system.createProvider(connectionString); + const provider = await system.createProvider(remote); await provider.start(); if (provider.isConnected() === false) { @@ -71,74 +72,74 @@ async function main() { const builder = new flatbuffers.Builder(DatalayerSystem.defaultFlatbuffersInitialSize); const offset = InertialValue.createInertialValue(builder, 30, -442, 911); builder.finish(offset); - var inertialValue = builder.asUint8Array(); + const inertialValue = builder.asUint8Array(); const now = new Date(); // Create all static nodes. const staticNodes = [ - Node.createStatic(DataTypes.bool8, DataRanges.bool8.getMax()), - Node.createStatic(DataTypes.int8, DataRanges.int8.getMax()), - Node.createStatic(DataTypes.uint8, DataRanges.uint8.getMax()), - Node.createStatic(DataTypes.int16, DataRanges.int16.getMax()), - Node.createStatic(DataTypes.uint16, DataRanges.uint16.getMax()), - Node.createStatic(DataTypes.int32, DataRanges.int32.getMax()), - Node.createStatic(DataTypes.uint32, DataRanges.uint32.getMax()), - Node.createStatic(DataTypes.int64, DataRanges.int64.getMax()), - Node.createStatic(DataTypes.uint64, DataRanges.uint64.getMax()), - Node.createStatic(DataTypes.float, DataRanges.float.getMax()), - Node.createStatic(DataTypes.double, DataRanges.double.getMax()), - Node.createStatic(DataTypes.string, 'String_0'), - Node.createStatic(DataTypes.timestamp, now), - Node.createStatic(DataTypes.inertialValue, inertialValue), - Node.createStatic(DataTypes.arbool8, [true, false, true]), - Node.createStatic(DataTypes.arint8, [DataRanges.int8.getMin(), -1, 0, DataRanges.int8.getMax()]), - Node.createStatic(DataTypes.aruint8, [DataRanges.uint8.getMin(), DataRanges.uint8.getMax()]), - Node.createStatic(DataTypes.arint16, [DataRanges.int16.getMin(), -1, 0, DataRanges.int16.getMax()]), - Node.createStatic(DataTypes.aruint16, [DataRanges.uint16.getMin(), DataRanges.uint16.getMax()]), - Node.createStatic(DataTypes.arint32, [DataRanges.int32.getMin(), -1, 0, DataRanges.int32.getMax()]), - Node.createStatic(DataTypes.aruint32, [DataRanges.uint32.getMin(), DataRanges.uint32.getMax()]), - Node.createStatic(DataTypes.arint64, [DataRanges.int64.getMin(), -1n, 0n, DataRanges.int64.getMax()]), - Node.createStatic(DataTypes.aruint64, [DataRanges.uint64.getMin(), DataRanges.uint64.getMax()]), - Node.createStatic(DataTypes.arfloat, [DataRanges.float.getMin(), -1.0, 0.0, DataRanges.float.getMax()]), - Node.createStatic(DataTypes.ardouble, [DataRanges.double.getMin(), -1.0, 0.0, DataRanges.double.getMax()]), - Node.createStatic(DataTypes.arstring, ['Blue', 'Red', 'Orange']), - Node.createStatic(DataTypes.artimestamp, [now, now, now]) + Node.createStatic(DATA_TYPES.bool8, DATA_RANGES.bool8.getMax()), + Node.createStatic(DATA_TYPES.int8, DATA_RANGES.int8.getMax()), + Node.createStatic(DATA_TYPES.uint8, DATA_RANGES.uint8.getMax()), + Node.createStatic(DATA_TYPES.int16, DATA_RANGES.int16.getMax()), + Node.createStatic(DATA_TYPES.uint16, DATA_RANGES.uint16.getMax()), + Node.createStatic(DATA_TYPES.int32, DATA_RANGES.int32.getMax()), + Node.createStatic(DATA_TYPES.uint32, DATA_RANGES.uint32.getMax()), + Node.createStatic(DATA_TYPES.int64, DATA_RANGES.int64.getMax()), + Node.createStatic(DATA_TYPES.uint64, DATA_RANGES.uint64.getMax()), + Node.createStatic(DATA_TYPES.float, DATA_RANGES.float.getMax()), + Node.createStatic(DATA_TYPES.double, DATA_RANGES.double.getMax()), + Node.createStatic(DATA_TYPES.string, 'String_0'), + Node.createStatic(DATA_TYPES.timestamp, now), + Node.createStatic(DATA_TYPES.inertialValue, inertialValue), + Node.createStatic(DATA_TYPES.arbool8, [true, false, true]), + Node.createStatic(DATA_TYPES.arint8, [DATA_RANGES.int8.getMin(), -1, 0, DATA_RANGES.int8.getMax()]), + Node.createStatic(DATA_TYPES.aruint8, [DATA_RANGES.uint8.getMin(), DATA_RANGES.uint8.getMax()]), + Node.createStatic(DATA_TYPES.arint16, [DATA_RANGES.int16.getMin(), -1, 0, DATA_RANGES.int16.getMax()]), + Node.createStatic(DATA_TYPES.aruint16, [DATA_RANGES.uint16.getMin(), DATA_RANGES.uint16.getMax()]), + Node.createStatic(DATA_TYPES.arint32, [DATA_RANGES.int32.getMin(), -1, 0, DATA_RANGES.int32.getMax()]), + Node.createStatic(DATA_TYPES.aruint32, [DATA_RANGES.uint32.getMin(), DATA_RANGES.uint32.getMax()]), + Node.createStatic(DATA_TYPES.arint64, [DATA_RANGES.int64.getMin(), -1n, 0n, DATA_RANGES.int64.getMax()]), + Node.createStatic(DATA_TYPES.aruint64, [DATA_RANGES.uint64.getMin(), DATA_RANGES.uint64.getMax()]), + Node.createStatic(DATA_TYPES.arfloat, [DATA_RANGES.float.getMin(), -1.0, 0.0, DATA_RANGES.float.getMax()]), + Node.createStatic(DATA_TYPES.ardouble, [DATA_RANGES.double.getMin(), -1.0, 0.0, DATA_RANGES.double.getMax()]), + Node.createStatic(DATA_TYPES.arstring, ['Blue', 'Red', 'Orange']), + Node.createStatic(DATA_TYPES.artimestamp, [now, now, now]) ] // Create all dynamic nodes. const dynamicNodes = [ - Node.createDynamic(DataTypes.bool8, 0), - Node.createDynamic(DataTypes.int8, 0), - Node.createDynamic(DataTypes.uint8, 0), - Node.createDynamic(DataTypes.int16, 0), - Node.createDynamic(DataTypes.uint16, 0), - Node.createDynamic(DataTypes.int32, 0), - Node.createDynamic(DataTypes.uint32, 0), - Node.createDynamic(DataTypes.int64, 0n), - Node.createDynamic(DataTypes.uint64, 0n), - Node.createDynamic(DataTypes.float, 0), - Node.createDynamic(DataTypes.double, 0), - Node.createDynamic(DataTypes.string, 'String_0'), - Node.createDynamic(DataTypes.timestamp, new Date()), - Node.createDynamic(DataTypes.inertialValue, inertialValue), - Node.createDynamic(DataTypes.arbool8, [true, false, true, false, true, false, true, false, true, false]), - Node.createDynamic(DataTypes.arint8, [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4]), - Node.createDynamic(DataTypes.aruint8, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]), - Node.createDynamic(DataTypes.arint16, [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4]), - Node.createDynamic(DataTypes.aruint16, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]), - Node.createDynamic(DataTypes.arint32, [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4]), - Node.createDynamic(DataTypes.aruint32, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]), - Node.createDynamic(DataTypes.arint64, [-5n, -4n, -3n, -2n, -1n, 0n, 1n, 2n, 3n, 4n]), - Node.createDynamic(DataTypes.aruint64, [0n, 1n, 2n, 3n, 4n, 5n, 6n, 7n, 8n, 9n]), - Node.createDynamic(DataTypes.arfloat, [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]), - Node.createDynamic(DataTypes.ardouble, [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]), - Node.createDynamic(DataTypes.arstring, ['String_0', 'String_1', 'String_2', 'String_3', 'String_4', 'String_5', 'String_6', 'String_7', 'String_8', 'String_9']), - Node.createDynamic(DataTypes.artimestamp, [now, now, now, now, now, now, now, now]) + Node.createDynamic(DATA_TYPES.bool8, 0), + Node.createDynamic(DATA_TYPES.int8, 0), + Node.createDynamic(DATA_TYPES.uint8, 0), + Node.createDynamic(DATA_TYPES.int16, 0), + Node.createDynamic(DATA_TYPES.uint16, 0), + Node.createDynamic(DATA_TYPES.int32, 0), + Node.createDynamic(DATA_TYPES.uint32, 0), + Node.createDynamic(DATA_TYPES.int64, 0n), + Node.createDynamic(DATA_TYPES.uint64, 0n), + Node.createDynamic(DATA_TYPES.float, 0), + Node.createDynamic(DATA_TYPES.double, 0), + Node.createDynamic(DATA_TYPES.string, 'String_0'), + Node.createDynamic(DATA_TYPES.timestamp, new Date()), + Node.createDynamic(DATA_TYPES.inertialValue, inertialValue), + Node.createDynamic(DATA_TYPES.arbool8, [true, false, true, false, true, false, true, false, true, false]), + Node.createDynamic(DATA_TYPES.arint8, [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4]), + Node.createDynamic(DATA_TYPES.aruint8, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]), + Node.createDynamic(DATA_TYPES.arint16, [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4]), + Node.createDynamic(DATA_TYPES.aruint16, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]), + Node.createDynamic(DATA_TYPES.arint32, [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4]), + Node.createDynamic(DATA_TYPES.aruint32, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]), + Node.createDynamic(DATA_TYPES.arint64, [-5n, -4n, -3n, -2n, -1n, 0n, 1n, 2n, 3n, 4n]), + Node.createDynamic(DATA_TYPES.aruint64, [0n, 1n, 2n, 3n, 4n, 5n, 6n, 7n, 8n, 9n]), + Node.createDynamic(DATA_TYPES.arfloat, [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]), + Node.createDynamic(DATA_TYPES.ardouble, [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]), + Node.createDynamic(DATA_TYPES.arstring, ['String_0', 'String_1', 'String_2', 'String_3', 'String_4', 'String_5', 'String_6', 'String_7', 'String_8', 'String_9']), + Node.createDynamic(DATA_TYPES.artimestamp, [now, now, now, now, now, now, now, now]) ] // Create map with key address and value node for the callback functions. - var addressToNode = new Map() + let addressToNode = new Map() // Add all static nodes to the map. staticNodes.forEach(node => { diff --git a/samples-node/datalayer.provider.alldata/src/datalayerhelper.ts b/samples-node/datalayer.provider.alldata/src/datalayerhelper.ts deleted file mode 100644 index 47f1c61c..00000000 --- a/samples-node/datalayer.provider.alldata/src/datalayerhelper.ts +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) 2021-2022 Bosch Rexroth AG - -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the 'Software'), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -/** -* This class provides auxiliary methods to create ctrlX Datalayer client and provider connection strings to ctrlX CORE devices. -* It can be used for both running in an app build environment(QEMU VM) and within the snap environment on the ctrlX CORE. -* -* Feel free to use it in your projects and to change it if necessary. -* -* For ease of use, the default values for IP address, user, password and SSL port are chosen to match the settings of a -* newly created ctrlX CORE device: -* -* ip="192.168.1.1" -* user="boschrexroth" -* password="boschrexroth" -* sslPort=443 -* -* with these variables, the tcp connection string can be formatted as follows: -* -* tcp://{user}:{password}@{ip}?sslport={sslPort} -* -* If these values do not suit your use case, explicitly pass the parameters that require different values. -* -* Here some examples: -* -* 1. ctrlX CORE or ctrlX CORE virtual with another IP address, user and password: -* -* const connectionString = DatalayerHelper.getConnectionString({ ip: "192.168.1.100", user: "admin", password: "-$_U/{X$aG}Z3/e<" }) -* -* 2. ctrlX CORE virtual with port forwarding running on the same host as the app build environment (QEMU VM): -* -* const connectionString = DatalayerHelper.getConnectionString({ ip: "10.0.2.2", sslPort: 8443 }) -* -* Remarks: -* 10.0.2.2 is the IP address of the host from the point of view of the app build environment(QEMU VM). -* 8443 is the host port which is forwarded to the SSL port(=433) of the ctrlX CORE virtual -* -* 3. ctrlX CORE virtual with port forwarding running on windows build environment (MS Visual Studio): -* -* const connectionString = DatalayerHelper.getConnectionString({ ip: "127.0.0.1", sslPort: 8443 }) -* -* Remarks: -* 127.0.0.1 is the IP address of the ctrlX virtual on the windows host system. -* 8443 is the host port which is forwarded to the SSL port(=433) of the ctrlX CORE virtual -* -* IMPORTANT: -* You need not change the parameter settings before building a snap and installing the snap on a ctrlX CORE. -* The method detects the snap environment and uses automatically inter process communication. -* Therefor the connection string to the ctrlX Datalayer is: "ipc://" -*/ -class DatalayerHelper { - - /** - * Combines a ctrlX Datalayer connection string. - * @param ip: IP address of the ctrlX CORE. Use "10.0.2.2" to connect to a ctrlX CORE virtual with port forwarding - * @param user: Name of the user - * @param password: Password of the user - * @param sslPort: Port number for a SSL connection. ctrlX CORE virtual with port forwarding: Use the host port (default 8443) forwarded to port 22 of the ctrlX virtual - * @returns The connection string: ipc connection string if running inside snap otherwise tcp connection string - */ - public static getConnectionString({ ip = "192.168.1.1", user = "boschrexroth", password = "boschrexroth", sslPort = 443 }: { ip?: string, user?: string, password?: string, sslPort?: Number }): string { - if (typeof process.env.SNAP_NAME !== 'undefined' && process.env.SNAP_NAME !== 'node') { - return "ipc://"; - } - - return 'tcp://' + user + ':' + password + '@' + ip + '?sslport=' + sslPort; - } -} - -export = DatalayerHelper; \ No newline at end of file diff --git a/samples-node/datalayer.provider.alldata/src/dataranges.ts b/samples-node/datalayer.provider.alldata/src/dataranges.ts index 9352de00..e6a719fb 100644 --- a/samples-node/datalayer.provider.alldata/src/dataranges.ts +++ b/samples-node/datalayer.provider.alldata/src/dataranges.ts @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2022 Bosch Rexroth AG +// Copyright (c) 2021-2023 Bosch Rexroth AG // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the 'Software'), to deal @@ -23,7 +23,7 @@ import DataRange from './datarange'; /** * The data ranges of all data types. */ -const DataRanges = { +const DATA_RANGES = { /** * bool 8 bit @@ -81,4 +81,4 @@ const DataRanges = { double: DataRange.create(-1.7976931348623157e+308, 1.7976931348623157e+308), } -export = DataRanges; \ No newline at end of file +export = DATA_RANGES; \ No newline at end of file diff --git a/samples-node/datalayer.provider.alldata/src/datatypes.ts b/samples-node/datalayer.provider.alldata/src/datatypes.ts index 32f1bdd4..fa1fad5d 100644 --- a/samples-node/datalayer.provider.alldata/src/datatypes.ts +++ b/samples-node/datalayer.provider.alldata/src/datatypes.ts @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2022 Bosch Rexroth AG +// Copyright (c) 2021-2023 Bosch Rexroth AG // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the 'Software'), to deal @@ -25,7 +25,7 @@ import DataType from './datatype'; /** * The data types with variant type and target address. */ -const DataTypes = { +const DATA_TYPES = { /** * bool 8 bit */ @@ -162,4 +162,4 @@ const DataTypes = { artimestamp: DataType.create('array-of-timestamp', VariantTypes.arstring, 'types/datalayer/array-of-timestamp'), } -export = DataTypes; \ No newline at end of file +export = DATA_TYPES; \ No newline at end of file diff --git a/samples-node/datalayer.provider.alldata/src/node.ts b/samples-node/datalayer.provider.alldata/src/node.ts index 660b4c63..f58a5088 100644 --- a/samples-node/datalayer.provider.alldata/src/node.ts +++ b/samples-node/datalayer.provider.alldata/src/node.ts @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2022 Bosch Rexroth AG +// Copyright (c) 2021-2023 Bosch Rexroth AG // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the 'Software'), to deal @@ -18,8 +18,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -// MetadataUtils -import * as MetadataUtils from 'ctrlx-datalayer/dist/metadata-utils'; +// DatalayerSystem import DatalayerSystem from 'ctrlx-datalayer/dist/datalayersystem'; // Flatbuffers @@ -27,7 +26,11 @@ import * as flatbuffers from 'flatbuffers'; import { InertialValue } from './sample/schema/inertial-value'; import DataType from './datatype'; -import DataTypes from './datatypes'; +import DATA_TYPES from './datatypes'; +import DatalayerSystem from 'ctrlx-datalayer/dist/datalayersystem'; + +// Utils +import * as MetadataUtils from 'ctrlx-datalayer/dist/metadata-utils'; /** * The interface INode @@ -186,81 +189,81 @@ class Node implements INode { */ public incrementValue(now: Date) { switch (this.dataType) { - case DataTypes.bool8: + case DATA_TYPES.bool8: this.value = !this.value; break; - case DataTypes.int8: - case DataTypes.uint8: - case DataTypes.int16: - case DataTypes.uint16: - case DataTypes.int32: - case DataTypes.uint32: + case DATA_TYPES.int8: + case DATA_TYPES.uint8: + case DATA_TYPES.int16: + case DATA_TYPES.uint16: + case DATA_TYPES.int32: + case DATA_TYPES.uint32: this.value += 1; break; - case DataTypes.int64: - case DataTypes.uint64: + case DATA_TYPES.int64: + case DATA_TYPES.uint64: this.value += 1n; break; - case DataTypes.float: - case DataTypes.double: + case DATA_TYPES.float: + case DATA_TYPES.double: this.value += 0.1; break; - case DataTypes.string: + case DATA_TYPES.string: this.value = this.incrementStringValue(this.value, '_'); break; - case DataTypes.timestamp: + case DATA_TYPES.timestamp: this.value = now; break; - case DataTypes.arbool8: - for (var i = 0; i < this.value.length; ++i) { + case DATA_TYPES.arbool8: + for (let i = 0; i < this.value.length; ++i) { this.value[i] = !this.value[i]; } break; - case DataTypes.arint8: - case DataTypes.aruint8: - case DataTypes.arint16: - case DataTypes.aruint16: - case DataTypes.arint32: - case DataTypes.aruint32: + case DATA_TYPES.arint8: + case DATA_TYPES.aruint8: + case DATA_TYPES.arint16: + case DATA_TYPES.aruint16: + case DATA_TYPES.arint32: + case DATA_TYPES.aruint32: for (let i = 0; i < this.value.length; ++i) { this.value[i] = this.value[i] + 1; } break; - case DataTypes.arfloat: - case DataTypes.ardouble: + case DATA_TYPES.arfloat: + case DATA_TYPES.ardouble: for (let i = 0; i < this.value.length; ++i) { this.value[i] = this.value[i] + 0.1; } break; - case DataTypes.arint64: - case DataTypes.aruint64: + case DATA_TYPES.arint64: + case DATA_TYPES.aruint64: for (let i = 0; i < this.value.length; ++i) { this.value[i] = this.value[i] + 1n; } break; - case DataTypes.arstring: + case DATA_TYPES.arstring: for (let i = 0; i < this.value.length; ++i) { this.value[i] = this.incrementStringValue(this.value[i], '_'); } break; - case DataTypes.artimestamp: + case DATA_TYPES.artimestamp: for (let i = 0; i < this.value.length; ++i) { this.value[i] = now; } break; - case DataTypes.inertialValue: + case DATA_TYPES.inertialValue: const oldInertialValue = InertialValue.getRootAsInertialValue(new flatbuffers.ByteBuffer(this.value)) const builder = new flatbuffers.Builder(DatalayerSystem.defaultFlatbuffersInitialSize); const offset = InertialValue.createInertialValue(builder, @@ -278,10 +281,10 @@ class Node implements INode { * @returns */ private incrementStringValue(text: string, separator: string): string { - var separatorIndex = text.indexOf(separator); - var prefix = text.substring(0, separatorIndex); - var postfix = text.substring(separatorIndex + 1); - var number = Number.parseInt(postfix); + const separatorIndex = text.indexOf(separator); + const prefix = text.substring(0, separatorIndex); + const postfix = text.substring(separatorIndex + 1); + let number = Number.parseInt(postfix); return `${prefix}${separator}${++number}`; } } diff --git a/samples-node/datalayer.provider/.vscode/tasks.json b/samples-node/datalayer.provider/.vscode/tasks.json index 3d24d1b2..32bbc133 100644 --- a/samples-node/datalayer.provider/.vscode/tasks.json +++ b/samples-node/datalayer.provider/.vscode/tasks.json @@ -1,61 +1,233 @@ { - "version": "2.0.0", - "tasks": [ - { - "label": "build snap amd64", - "type": "shell", - "command": "bash", - "args": [ - "build-snap-amd64.sh" - ], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build snap arm64", - "type": "shell", - "command": "bash", - "args": [ - "build-snap-arm64.sh" - ], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - - { - "label": "npm clean", - "group": { - "kind": "build", - "isDefault": true - }, - "type": "shell", - "problemMatcher": [], - "command": "rm -rf node_modules", - "options": { - "cwd": "${workspaceFolder}" - } - }, - { - "label": "npm install", - "group": { - "kind": "build", - "isDefault": true - }, - "type": "shell", - "problemMatcher": [], - "command": "npm install", - "options": { - "cwd": "${workspaceFolder}" - }, - "dependsOn": [ - "npm clean" - ] - }, - ] + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "npm clean", + "group": { + "kind": "build", + "isDefault": true + }, + "type": "shell", + "problemMatcher": [], + "command": "rm -rf node_modules", + "options": { + "cwd": "${workspaceFolder}" + } + }, + { + "label": "npm install", + "group": { + "kind": "build", + "isDefault": true + }, + "type": "shell", + "problemMatcher": [], + "command": "npm install", + "options": { + "cwd": "${workspaceFolder}" + }, + "dependsOn": [ + "npm clean" + ] + }, + { + "label": "Build snap amd64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-amd64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build snap arm64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-arm64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + ], + "inputs": [ + { + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", + "type": "promptString", + "description": "IP address", + "default": "192.168.1.1" + }, + { + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", + "type": "promptString", + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" + }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" + } + ] } \ No newline at end of file diff --git a/samples-node/datalayer.provider/package.json b/samples-node/datalayer.provider/package.json index 6725914b..5c385f2a 100644 --- a/samples-node/datalayer.provider/package.json +++ b/samples-node/datalayer.provider/package.json @@ -11,15 +11,15 @@ "dist" ], "devDependencies": { - "@types/node": "^18.8.4", - "@typescript-eslint/parser": "^5.40.0", - "eslint": "^8.25.0", - "typescript": "^4.8.4", - "ts-node": "^10.8.1" + "@types/node": "^18.13.0", + "@typescript-eslint/parser": "^5.52.0", + "eslint": "^8.34.0", + "typescript": "^4.9.5", + "ts-node": "^10.9.1" }, "dependencies": { - "ctrlx-datalayer": "^1.5.0", - "ctrlx-datalayer-flatbuffers": "^1.18.0" + "ctrlx-datalayer": "^1.6.0", + "ctrlx-datalayer-flatbuffers": "^1.20.0" }, "scripts": { "getName": "echo $npm_package_name", diff --git a/samples-node/datalayer.provider/snap/snapcraft.yaml b/samples-node/datalayer.provider/snap/snapcraft.yaml index b300451f..8d7a5127 100644 --- a/samples-node/datalayer.provider/snap/snapcraft.yaml +++ b/samples-node/datalayer.provider/snap/snapcraft.yaml @@ -3,16 +3,16 @@ # Snapcraft references # See https://snapcraft.io/docs/snapcraft-yaml-reference name: ctrlx-node-datalayer-provider -version: '1.0.0' +version: "1.0.0" summary: Data Layer provider sample written in Node.js for ctrlX. description: | The sample demonstrates how to provide nodes to the ctrlX Data Layer tree. The provider creates nodes with types of int/double/string. Also a complex type encoded by https://google.github.io/flatbuffers/ is provided. -confinement: strict -#confinement: devmode +confinement: strict +#confinement: devmode #icon: assets/icons/ICONHERE.png -grade: stable # must be 'stable' to release into candidate/stable channels +grade: stable # must be 'stable' to release into candidate/stable channels base: core20 type: app @@ -30,13 +30,13 @@ parts: app: source: . build-environment: - # Set the node version here. We recommend to use the latest LTS version. - - NODE_VERSION: "16.15.1" - + # Set the node version here. We recommend to use the latest LTS version. + - NODE_VERSION: "18.15.0" + # We don't use the npm plugin here, because it has no X-build capability (can't build arm64 target snaps on amd64). # plugin: npm - # npm-node-version: "16.15.1" - plugin: nil + # npm-node-version: "18.15.0" + plugin: nil override-build: | # set target arch if [ $SNAPCRAFT_TARGET_ARCH == "arm64" ]; then @@ -53,14 +53,11 @@ parts: curl $node_uri | tar xzf - -C $SNAPCRAFT_PART_INSTALL/ --no-same-owner --strip-components=1 fi - # setup npm - npm config set unsafe-perm true - # install the app (full) to compile (tsc -> ./dist) - npm install + npm install --unsafe-perm # pack and install the app (only production) - npm install -g --prefix $SNAPCRAFT_PART_INSTALL $(npm pack . | tail -1) --only=prod --production --no-fund + npm install -g --prefix $SNAPCRAFT_PART_INSTALL $(npm pack . | tail -1) --only=prod --production --no-fund --unsafe-perm # remove ctrlx-datalayer prebuilds of unused archs to reduce snap size package_name=$(npm run getName -s) @@ -76,4 +73,4 @@ plugs: datalayer: interface: content content: datalayer - target: $SNAP_DATA/.datalayer \ No newline at end of file + target: $SNAP_DATA/.datalayer diff --git a/samples-node/datalayer.provider/src/app.ts b/samples-node/datalayer.provider/src/app.ts index 87d5f13c..ec8bc08f 100644 --- a/samples-node/datalayer.provider/src/app.ts +++ b/samples-node/datalayer.provider/src/app.ts @@ -1,7 +1,7 @@ #!/usr/bin/env node // !!! DO NOT REMOVE THE SHEBANG ON TOP OF THE FILE, WHICH SPECIFIES THIS APP TO BE EXECUTED BY NODE.JS !!! -// Copyright (c) 2021-2022 Bosch Rexroth AG +// Copyright (c) 2021-2023 Bosch Rexroth AG // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the 'Software'), to deal @@ -31,9 +31,9 @@ import IVariant from "ctrlx-datalayer/dist/variant.js"; import * as flatbuffers from 'flatbuffers'; import { InertialValue } from './sampleSchema'; -// MetadataUtils +// Utils import * as MetadataUtils from 'ctrlx-datalayer/dist/metadata-utils'; -import DatalayerHelper from './datalayerhelper'; +import { Remote } from 'ctrlx-datalayer/dist/remote'; // The main function async function main() { @@ -43,12 +43,12 @@ async function main() { // Starts the ctrlX Data Layer system without a new broker (startBroker = false) because one broker is already running on ctrlX device await system.start(false); - // Create a connection string with the parameters according to your environment (see DatalayerHelper class) - const connectionString = DatalayerHelper.getConnectionString({ ip: "192.168.1.1", sslPort: 443 }) - console.log('connection string:', connectionString) + // Create a remote address with the parameters according to your environment + const remote = Remote.build({ ip: "192.168.1.1", sslPort: 443 }) + console.log('connection string:', remote) //Create a Provider with the given remote address - const provider = await system.createProvider(connectionString); + const provider = await system.createProvider(remote); await provider.start(); if (provider.isConnected() === false) { diff --git a/samples-node/datalayer.provider/src/datalayerhelper.ts b/samples-node/datalayer.provider/src/datalayerhelper.ts deleted file mode 100644 index 47f1c61c..00000000 --- a/samples-node/datalayer.provider/src/datalayerhelper.ts +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) 2021-2022 Bosch Rexroth AG - -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the 'Software'), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -/** -* This class provides auxiliary methods to create ctrlX Datalayer client and provider connection strings to ctrlX CORE devices. -* It can be used for both running in an app build environment(QEMU VM) and within the snap environment on the ctrlX CORE. -* -* Feel free to use it in your projects and to change it if necessary. -* -* For ease of use, the default values for IP address, user, password and SSL port are chosen to match the settings of a -* newly created ctrlX CORE device: -* -* ip="192.168.1.1" -* user="boschrexroth" -* password="boschrexroth" -* sslPort=443 -* -* with these variables, the tcp connection string can be formatted as follows: -* -* tcp://{user}:{password}@{ip}?sslport={sslPort} -* -* If these values do not suit your use case, explicitly pass the parameters that require different values. -* -* Here some examples: -* -* 1. ctrlX CORE or ctrlX CORE virtual with another IP address, user and password: -* -* const connectionString = DatalayerHelper.getConnectionString({ ip: "192.168.1.100", user: "admin", password: "-$_U/{X$aG}Z3/e<" }) -* -* 2. ctrlX CORE virtual with port forwarding running on the same host as the app build environment (QEMU VM): -* -* const connectionString = DatalayerHelper.getConnectionString({ ip: "10.0.2.2", sslPort: 8443 }) -* -* Remarks: -* 10.0.2.2 is the IP address of the host from the point of view of the app build environment(QEMU VM). -* 8443 is the host port which is forwarded to the SSL port(=433) of the ctrlX CORE virtual -* -* 3. ctrlX CORE virtual with port forwarding running on windows build environment (MS Visual Studio): -* -* const connectionString = DatalayerHelper.getConnectionString({ ip: "127.0.0.1", sslPort: 8443 }) -* -* Remarks: -* 127.0.0.1 is the IP address of the ctrlX virtual on the windows host system. -* 8443 is the host port which is forwarded to the SSL port(=433) of the ctrlX CORE virtual -* -* IMPORTANT: -* You need not change the parameter settings before building a snap and installing the snap on a ctrlX CORE. -* The method detects the snap environment and uses automatically inter process communication. -* Therefor the connection string to the ctrlX Datalayer is: "ipc://" -*/ -class DatalayerHelper { - - /** - * Combines a ctrlX Datalayer connection string. - * @param ip: IP address of the ctrlX CORE. Use "10.0.2.2" to connect to a ctrlX CORE virtual with port forwarding - * @param user: Name of the user - * @param password: Password of the user - * @param sslPort: Port number for a SSL connection. ctrlX CORE virtual with port forwarding: Use the host port (default 8443) forwarded to port 22 of the ctrlX virtual - * @returns The connection string: ipc connection string if running inside snap otherwise tcp connection string - */ - public static getConnectionString({ ip = "192.168.1.1", user = "boschrexroth", password = "boschrexroth", sslPort = 443 }: { ip?: string, user?: string, password?: string, sslPort?: Number }): string { - if (typeof process.env.SNAP_NAME !== 'undefined' && process.env.SNAP_NAME !== 'node') { - return "ipc://"; - } - - return 'tcp://' + user + ':' + password + '@' + ip + '?sslport=' + sslPort; - } -} - -export = DatalayerHelper; \ No newline at end of file diff --git a/samples-node/hello-world/.vscode/tasks.json b/samples-node/hello-world/.vscode/tasks.json index 760936ef..32bbc133 100644 --- a/samples-node/hello-world/.vscode/tasks.json +++ b/samples-node/hello-world/.vscode/tasks.json @@ -1,60 +1,233 @@ { - "version": "2.0.0", - "tasks": [ - { - "label": "build snap amd64", - "type": "shell", - "command": "bash", - "args": [ - "build-snap-amd64.sh" - ], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build snap arm64", - "type": "shell", - "command": "bash", - "args": [ - "build-snap-arm64.sh" - ], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "npm clean", - "group": { - "kind": "build", - "isDefault": true - }, - "type": "shell", - "problemMatcher": [], - "command": "rm -rf node_modules", - "options": { - "cwd": "${workspaceFolder}" - } - }, - { - "label": "npm install", - "group": { - "kind": "build", - "isDefault": true - }, - "type": "shell", - "problemMatcher": [], - "command": "npm install", - "options": { - "cwd": "${workspaceFolder}" - }, - "dependsOn": [ - "npm clean" - ] - }, - ] + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "npm clean", + "group": { + "kind": "build", + "isDefault": true + }, + "type": "shell", + "problemMatcher": [], + "command": "rm -rf node_modules", + "options": { + "cwd": "${workspaceFolder}" + } + }, + { + "label": "npm install", + "group": { + "kind": "build", + "isDefault": true + }, + "type": "shell", + "problemMatcher": [], + "command": "npm install", + "options": { + "cwd": "${workspaceFolder}" + }, + "dependsOn": [ + "npm clean" + ] + }, + { + "label": "Build snap amd64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-amd64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build snap arm64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-arm64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + ], + "inputs": [ + { + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", + "type": "promptString", + "description": "IP address", + "default": "192.168.1.1" + }, + { + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", + "type": "promptString", + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" + }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" + } + ] } \ No newline at end of file diff --git a/samples-node/hello-world/package.json b/samples-node/hello-world/package.json index b4219c40..f9f11936 100644 --- a/samples-node/hello-world/package.json +++ b/samples-node/hello-world/package.json @@ -11,11 +11,11 @@ "dist" ], "devDependencies": { - "@types/node": "^18.8.4", - "@typescript-eslint/parser": "^5.40.0", - "eslint": "^8.25.0", - "typescript": "^4.8.4", - "ts-node": "^10.8.1" + "@types/node": "^18.13.0", + "@typescript-eslint/parser": "^5.52.0", + "eslint": "^8.34.0", + "typescript": "^4.9.5", + "ts-node": "^10.9.1" }, "scripts": { "prepare": "npm run tsc", diff --git a/samples-node/hello-world/snap/snapcraft.yaml b/samples-node/hello-world/snap/snapcraft.yaml index 1fad3efb..fa0d4062 100644 --- a/samples-node/hello-world/snap/snapcraft.yaml +++ b/samples-node/hello-world/snap/snapcraft.yaml @@ -28,13 +28,13 @@ parts: app: source: . build-environment: - # Set the node version here. We recommend to use the latest LTS version. - - NODE_VERSION: "16.15.1" - + # Set the node version here. We recommend to use the latest LTS version. + - NODE_VERSION: "18.15.0" + # We don't use the npm plugin here, because it has no X-build capability (can't build arm64 target snaps on amd64). # plugin: npm - # npm-node-version: "16.15.1" - plugin: nil + # npm-node-version: "18.15.0" + plugin: nil override-build: | # set target arch if [ $SNAPCRAFT_TARGET_ARCH == "arm64" ]; then @@ -51,14 +51,11 @@ parts: curl $node_uri | tar xzf - -C $SNAPCRAFT_PART_INSTALL/ --no-same-owner --strip-components=1 fi - # setup npm - npm config set unsafe-perm true - # install the app (full) to compile (tsc -> ./dist) - npm install + npm install --unsafe-perm # pack and install the app (only production) - npm install -g --prefix $SNAPCRAFT_PART_INSTALL $(npm pack . | tail -1) --only=prod --production --no-fund + npm install -g --prefix $SNAPCRAFT_PART_INSTALL $(npm pack . | tail -1) --only=prod --production --no-fund --unsafe-perm # remove unused node_modules rm -rf ${SNAPCRAFT_PART_INSTALL}/lib/node_modules/npm diff --git a/samples-node/hello-world/src/app.ts b/samples-node/hello-world/src/app.ts index cb92d6b8..235a1cc4 100644 --- a/samples-node/hello-world/src/app.ts +++ b/samples-node/hello-world/src/app.ts @@ -1,28 +1,28 @@ -#!/usr/bin/env node -// !!! DO NOT REMOVE THE SHEBANG ON TOP OF THE FILE, WHICH SPECIFIES THIS APP TO BE EXECUTED BY NODE.JS !!! - -// Copyright (c) 2021-2022 Bosch Rexroth AG - -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the 'Software'), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -function helloWorld() { - setInterval(() => console.log('Hello World from Node.js!', new Date().toUTCString()), 1000) -}; - +#!/usr/bin/env node +// !!! DO NOT REMOVE THE SHEBANG ON TOP OF THE FILE, WHICH SPECIFIES THIS APP TO BE EXECUTED BY NODE.JS !!! + +// Copyright (c) 2021-2023 Bosch Rexroth AG + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the 'Software'), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +function helloWorld() { + setInterval(() => console.log('Hello World from Node.js!', new Date().toUTCString()), 1000) +}; + helloWorld(); \ No newline at end of file diff --git a/samples-node/solutions.webdav.interface/.editorconfig b/samples-node/solutions.webdav.interface/.editorconfig new file mode 100644 index 00000000..c1322dc7 --- /dev/null +++ b/samples-node/solutions.webdav.interface/.editorconfig @@ -0,0 +1,12 @@ +# EditorConfig is awesome: https://EditorConfig.org + +# top-most EditorConfig file +root = true + +[*] +indent_style = space +indent_size = 4 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = false +insert_final_newline = false \ No newline at end of file diff --git a/samples-node/solutions.webdav.interface/.eslintrc.js b/samples-node/solutions.webdav.interface/.eslintrc.js new file mode 100644 index 00000000..e74bfaa2 --- /dev/null +++ b/samples-node/solutions.webdav.interface/.eslintrc.js @@ -0,0 +1,27 @@ +module.exports = { + "env": { + "commonjs": true, + "es6": true, + "node": true, + "browser": false + }, + "extends": [ + "eslint:recommended", + ], + "parser": "@typescript-eslint/parser", + "globals": { + "Atomics": "readonly", + "SharedArrayBuffer": "readonly" + }, + "parserOptions": { + "sourceType": "module", + "ecmaVersion": 12, + "allowImportExportEverywhere": true, + "codeFrame": true + }, + "rules": { + }, + "plugins": [ + "@typescript-eslint" + ] +}; diff --git a/samples-node/solutions.webdav.interface/.vscode/launch.json b/samples-node/solutions.webdav.interface/.vscode/launch.json new file mode 100644 index 00000000..78375883 --- /dev/null +++ b/samples-node/solutions.webdav.interface/.vscode/launch.json @@ -0,0 +1,19 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Launch Program", + "type": "node", + "request": "launch", + "args": [ + "${workspaceFolder}/src/app.ts" + ], + "runtimeArgs": [ + "--nolazy", + "-r", + "ts-node/register" + ], + "sourceMaps": true + } + ] +} \ No newline at end of file diff --git a/samples-node/solutions.webdav.interface/README.md b/samples-node/solutions.webdav.interface/README.md new file mode 100644 index 00000000..983690c8 --- /dev/null +++ b/samples-node/solutions.webdav.interface/README.md @@ -0,0 +1,53 @@ +# Example: Using the Solutions WebDAV Interface + +## Introduction + +The sample demonstrates how to access the active and archived configurations of a ctrlX device remotely using the WebDAV protocol. + +## Description + +The application creates a WebDAV client and connects to a Virtual Control (localhost:8443) with the default credentials. +It executes some file operations using the following WebDAV library: https://github.com/perry-mitchell/webdav-client. + +## Getting Started + +1. Launch Visual Studio Code +2. Run 'npm install' in the terminal to get the dependencies +3. Press F5 to run or debug the app + +## Support +### Developer Community + +Please join the [Developer Community](https://developer.community.boschrexroth.com/) + +### SDK Forum + +Please visit the [SDK Forum](https://developer.community.boschrexroth.com/t5/ctrlX-AUTOMATION/ct-p/dcdev_community-bunit-dcae/) + +### Issues + +If you've found an error in these sample, please [file an issue](https://github.com/boschrexroth) + +## License + +MIT License + +Copyright (c) 2021-2022 Bosch Rexroth AG + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/samples-node/solutions.webdav.interface/package.json b/samples-node/solutions.webdav.interface/package.json new file mode 100644 index 00000000..5c027e9f --- /dev/null +++ b/samples-node/solutions.webdav.interface/package.json @@ -0,0 +1,28 @@ +{ + "name": "webdav-client", + "version": "1.0.0", + "description": "WebDAV-Client in Node.js for ctrlX", + "bin": { + "app": "dist/app.js" + }, + "author": "", + "license": "MIT", + "files": [ + "dist" + ], + "devDependencies": { + "@types/node": "^18.13.0", + "@typescript-eslint/eslint-plugin": "^5.52.0", + "@typescript-eslint/parser": "^5.52.0", + "eslint": "^8.34.0", + "ts-node": "^10.9.1", + "typescript": "^4.9.5" + }, + "scripts": { + "prepare": "npm run tsc", + "tsc": "tsc" + }, + "dependencies": { + "webdav": "^4.0.0" + } +} diff --git a/samples-node/solutions.webdav.interface/src/app.ts b/samples-node/solutions.webdav.interface/src/app.ts new file mode 100644 index 00000000..14515f5c --- /dev/null +++ b/samples-node/solutions.webdav.interface/src/app.ts @@ -0,0 +1,88 @@ +#!/usr/bin/env node +// !!! DO NOT REMOVE THE SHEBANG ON TOP OF THE FILE, WHICH SPECIFIES THIS APP TO BE EXECUTED BY NODE.JS !!! + +// Copyright (c) 2023 Bosch Rexroth AG + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the 'Software'), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +import { createClient } from "webdav"; + +// Disable TLS validation because of self-signed certificate on ctrlX +process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = '0'; + +// Uncomment this line if proxy should not be used (some proxies do not support WebDAV protocol) +// process.env["HTTPS_PROXY"] = ''; + +async function webdavClient() { + console.log('WebDAV-Client for Node.js!'); + + // Create client for virtual control + const client = createClient("https://localhost:8443/solutions/webdav", { + username: "boschrexroth", // The user needs 'manage configurations' permissions + password: "boschrexroth" + }); + + try { + // Create new directory + await client.createDirectory('webdavArchive'); + + // Create new file + await client.putFileContents('/webdavArchive/configuration.json', `{"description": "Created with WebDAV-Client"}`); + + // Get file contents as text + const txt = await client.getFileContents("/webdavArchive/configuration.json", { format: "text" }); + + // Get file contents binary + const bin = await client.getFileContents("/webdavArchive/configuration.json"); + + // Copy file + await client.copyFile('/webdavArchive/configuration.json', '/webdavArchive/configuration.json.copy'); + + // Get directory contents + const directoryContents = await client.getDirectoryContents("/webdavArchive"); + // returns a structure like: + // [ + // { + // filename: "/webdavArchive/configuration.json", + // basename: "configuration.json", + // lastmod: "Tue, 07 Mar 2023 23:24:11 GMT", + // size: 45, + // type: "file" + // }, + // { + // filename: "/webdavArchive/configuration.json.copy", + // basename: "configuration.json.copy", + // lastmod: "Tue, 07 Mar 2023 23:24:11 GMT", + // size: 45, + // type: "file" + // }, + //] + + // Delete file + await client.deleteFile('/webdavArchive/configuration.json.copy'); + + // Delete directory + await client.deleteFile('webdavArchive'); + + } catch(err) { + console.log(`${err}`); + } +} + +webdavClient(); \ No newline at end of file diff --git a/samples-node/solutions.webdav.interface/tsconfig.json b/samples-node/solutions.webdav.interface/tsconfig.json new file mode 100644 index 00000000..7102ebf8 --- /dev/null +++ b/samples-node/solutions.webdav.interface/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "target": "es2021", + "module": "commonjs", + "outDir": "./dist", + "rootDir": "./src", + "strict": true, + "moduleResolution": "node", + "noImplicitAny": false, + "esModuleInterop": true, + "sourceMap": false + }, + "include": [ + "./src/**/*" + ], + "lib": [ + "ES2021" + ], +} \ No newline at end of file diff --git a/samples-python/appdata/.vscode/tasks.json b/samples-python/appdata/.vscode/tasks.json index 72aaf14d..6fe5bc49 100644 --- a/samples-python/appdata/.vscode/tasks.json +++ b/samples-python/appdata/.vscode/tasks.json @@ -1,36 +1,213 @@ { - // See https://go.microsoft.com/fwlink/?LinkId=733558 - // for the documentation about the tasks.json format - "version": "2.0.0", - "tasks": [ - { - "label": "0 Install venv and packages", - "type": "shell", - "command": "bash", - "args": ["install-venv.sh"], - "problemMatcher": [] - }, - { - "label": "build snap amd64", - "type": "shell", - "command": "bash", - "args": ["build-snap-amd64.sh"], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build snap arm64", - "type": "shell", - "command": "bash", - "args": ["build-snap-arm64.sh"], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - } - ] + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "Install venv", + "type": "shell", + "command": "bash", + "args": [ + "install-venv.sh" + ], + "problemMatcher": [] + }, + { + "label": "Build snap amd64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-amd64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build snap arm64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-arm64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + ], + "inputs": [ + { + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", + "type": "promptString", + "description": "IP address", + "default": "192.168.1.1" + }, + { + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", + "type": "promptString", + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" + }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" + } + ] } \ No newline at end of file diff --git a/samples-python/appdata/README.md b/samples-python/appdata/README.md index 0b21fff9..b6dc934e 100644 --- a/samples-python/appdata/README.md +++ b/samples-python/appdata/README.md @@ -6,11 +6,9 @@ This Python sample app shows how to persist application data in ctrlX environmen ## Function Description -This app uses a web server to listen for events regarding loading and save configuration data. +This app uses a web server to listen for events regarding loading and saving configuration data. -Running in the snap environment of a ctrlX CORE therefor a web socket connection is used. - -In debug mode (running in the build environment) a TCP/IP connection is used. +Running in the snap environment of a ctrlX CORE therefor a web socket connection is used. In the build environment a TCP/IP connection is used. ## Implementation Description @@ -18,7 +16,7 @@ __main.py__ starts the web server in TCP or Unix socket mode. The package __web__ contains the web server implementation using the build in Python module http.server. For encoding and decoding JSON Web Tokens the Python library pyjwt is used. -The folder __configs__ contains the file package-manifest.json. It is used to register the snap with in the ctrlX CORE as participant of the configuration load/store mechanism. +The folder __configs__ contains the file package-manifest.json. It is used to register the snap within the ctrlX CORE as participant of the configuration load/store mechanism. ___ diff --git a/samples-python/appdata/appdata/app_data_control.py b/samples-python/appdata/appdata/app_data_control.py index 44c3dd33..f48c1dca 100644 --- a/samples-python/appdata/appdata/app_data_control.py +++ b/samples-python/appdata/appdata/app_data_control.py @@ -62,12 +62,12 @@ def __init__(self, storage_folder_name="AppDataSamplePy", storage_file_name="app } def load(self): - print("INFO Starting load routine") + print("INFO Starting load routine", flush=True) path = self.storage_file # Check if storagefile exist, if not reset with inital data if os.path.isfile(path) is False: - print("INFO No application file exist") + print("INFO No application file exist", flush=True) return AppDataControl.set_default(self) # Open JSON AppData file @@ -82,19 +82,19 @@ def load(self): if result is True: print("INFO Loaded application data from file", - path, "successfully") + path, "successfully", flush=True) return True else: print("ERROR Loading application data from file", - path, "failed! Data type missmatch") + path, "failed! Data type missmatch", flush=True) return False else: print("ERROR Loading application data from file", - path, "failed! Data type is not dict") + path, "failed! Data type is not dict", flush=True) return False def save(self): - print("INFO Starting save routine") + print("INFO Starting save routine", flush=True) # Check if storage location exists result = AppDataControl.ensure_storage_location(self) @@ -105,10 +105,10 @@ def save(self): with open(path, 'w') as filewrite: json.dump(AppDataControl.get_appdata(self), filewrite) - print("INFO Saved application data to file: '", path) + print("INFO Saved application data to file: '", path, flush=True) return True - print("ERROR Saving application data not possible") + print("ERROR Saving application data not possible", flush=True) return False def set_default(self): @@ -123,7 +123,7 @@ def set_default(self): result = AppDataControl.set_appdata(self, data) - print("INFO Created default application file") + print("INFO Created default application file", flush=True) return AppDataControl.save(self) def ensure_storage_location(self): @@ -134,21 +134,21 @@ def ensure_storage_location(self): if 'SNAP' in os.environ: solutions_path = os.path.join(self.common_path, "solutions") for i in range(4): - print("INFO Check if content interface is mounted") + print("INFO Check if content interface is mounted", flush=True) if os.path.isdir(solutions_path) is False: - print("ERROR Content interface is not mounted: Attempt", i+1) + print("ERROR Content interface is not mounted: Attempt", i+1, flush=True) time.sleep(1.0) if i >= 4: return False else: - print("INFO Content interface is mounted") + print("INFO Content interface is mounted", flush=True) if os.path.isdir(path) is False: try: - print("INFO Creating storage location: ", path) + print("INFO Creating storage location: ", path, flush=True) os.makedirs(path) except OSError: - print("ERROR Creating storage location", path, "failed!") + print("ERROR Creating storage location", path, "failed!", flush=True) return False return True @@ -158,7 +158,7 @@ def set_appdata(self, data): if self.appdata.keys() <= data.keys(): self.appdata = data return True - print("ERROR Setting application data failed! Present data is not a subset of new data") + print("ERROR Setting application data failed! Present data is not a subset of new data", flush=True) return False def get_appdata(self): diff --git a/samples-python/appdata/main.py b/samples-python/appdata/main.py index ec6ba149..1f535e36 100644 --- a/samples-python/appdata/main.py +++ b/samples-python/appdata/main.py @@ -23,7 +23,6 @@ # SOFTWARE. import os -import time from http.server import HTTPServer from web.server import Server, UnixSocketHttpServer @@ -39,7 +38,7 @@ def main(): webserver.serve_forever() - print(time.asctime(), 'Server DOWN') + print("Server DOWN", flush=True) def create_webserver_tcp(): @@ -47,7 +46,7 @@ def create_webserver_tcp(): hostname = 'localhost' webserver = HTTPServer(('', serverPort), Server) - print(time.asctime(), 'Server UP -TCP/IP- ', hostname, ':', serverPort) + print("Server started, listening on TCP SOCKET", hostname, ':', serverPort, flush=True) return webserver @@ -62,7 +61,7 @@ def create_webserver_unixsock(): pass webserver = UnixSocketHttpServer(sock_file, Server) - print(time.asctime(), 'Server UP -UNIX SOCKET- ', sock_file) + print('Server started, listening on UNIX SOCKET', sock_file, flush=True) return webserver diff --git a/samples-python/appdata/setup.py b/samples-python/appdata/setup.py index f8573eb1..6cecc80c 100644 --- a/samples-python/appdata/setup.py +++ b/samples-python/appdata/setup.py @@ -1,7 +1,7 @@ from setuptools import setup setup(name = 'sdk-py-appdata', - version='2.0.0', + version='2.3.0', description = 'This sample demonstrates how to persist your application data in ctrlX environment', author = 'SDK Team', packages = ['appdata','web'], diff --git a/samples-python/appdata/snap/snapcraft.yaml b/samples-python/appdata/snap/snapcraft.yaml index 2430443f..23e9ffb3 100644 --- a/samples-python/appdata/snap/snapcraft.yaml +++ b/samples-python/appdata/snap/snapcraft.yaml @@ -1,5 +1,5 @@ name: sdk-py-appdata -version: 2.0.0 +version: 2.3.0 summary: Application data sample written in Python for ctrlX title: sdk-py-appdata description: | diff --git a/samples-python/appdata/web/server.py b/samples-python/appdata/web/server.py index 9c1ba047..f69b75d6 100644 --- a/samples-python/appdata/web/server.py +++ b/samples-python/appdata/web/server.py @@ -49,7 +49,7 @@ class Server(BaseHTTPRequestHandler): def do_POST(self): # Check if url valid request_url = self.path - print("INFO REST Command:", request_url) + print("INFO REST Command:", request_url, flush=True) if request_url != Server.rest_url_load and request_url != Server.rest_url_save: self.send_error(HTTPStatus.FORBIDDEN) return @@ -62,9 +62,9 @@ def do_POST(self): result, token, token_decoded = token_validation.get_token(self.headers) if result is False or token_validation.is_authorized("rexroth-device.all.rwx") is False: self.send_error(HTTPStatus.UNAUTHORIZED) - print("ERROR Not authorized (Bearer invalid)") + print("ERROR Not authorized (Bearer invalid)", flush=True) return - print("INFO Check scope passed") + print("INFO Check scope passed", flush=True) # Get payload from request content_length = int(self.headers['Content-Length']) # Get the size of data @@ -74,7 +74,7 @@ def do_POST(self): # Check if payload contains config payload if payload.keys() != Server.config_payload.keys(): self.send_error(HTTPStatus.BAD_REQUEST) - print("ERROR wrong request payload") + print("ERROR wrong request payload", flush=True) return # Command evaluation @@ -85,35 +85,35 @@ def do_POST(self): # query: Check if loading is possible in the current system statecase "query" : # Hint: The phase 'query' is called 2 times: the first call asks for a setup mode change acknowledge and the second is called during normal load sequence if payload["phase"] == "query": - print("INFO Phase: query") + print("INFO Phase: query", flush=True) self.send_response(HTTPStatus.OK) self.end_headers() return # prepare: Perform any required preparatory steps elif payload["phase"] == "prepare": - print("INFO Phase: prepare") + print("INFO Phase: prepare", flush=True) self.send_response(HTTPStatus.OK) self.end_headers() return # validate: Perform post-processing steps, connect resources and resolve dependencies elif payload["phase"] == "validate": - print("INFO Phase: validate") + print("INFO Phase: validate", flush=True) self.send_response(HTTPStatus.OK) self.end_headers() return # activate (if phases 1-4 have been finished without problems): Establish desired run state of the device elif payload["phase"] == "activate": - print("INFO Phase: activate") + print("INFO Phase: activate", flush=True) self.send_response(HTTPStatus.OK) self.end_headers() return # abort (otherwise): Do NOT change run state of the device, clean up if required elif payload["phase"] == "abort": - print("INFO Phase: abort") + print("INFO Phase: abort", flush=True) # We return 204 as an default to satisfy the workflow # response.WriteHeader(http.StatusNoContent) self.send_response(HTTPStatus.OK) @@ -122,7 +122,7 @@ def do_POST(self): # load: Provide resources according to the data from the active configuration elif payload["phase"] == "load": - print("INFO Phase: load") + print("INFO Phase: load", flush=True) # This is were we can load our application data from current configuration if Server.app_data_control.load() is False: self.send_error(HTTPStatus.INTERNAL_SERVER_ERROR) @@ -141,7 +141,7 @@ def do_POST(self): # phases # Save: Serialize current resources into active configuration if payload["phase"] == "save": - print("INFO phase: save") + print("INFO phase: save", flush=True) # This is were we can save our application data into current configuration to be persistent # Set default data on save command every time because this sample has no additional application data Server.app_data_control.set_default() diff --git a/samples-python/appdata/web/token.py b/samples-python/appdata/web/token.py index 3586cd6c..1e9ed015 100644 --- a/samples-python/appdata/web/token.py +++ b/samples-python/appdata/web/token.py @@ -38,13 +38,13 @@ def get_token(self, header): self.token_decoded = jwt.decode(self.token, options={"verify_signature": False}) return True, self.token, self.token_decoded except jwt.DecodeError: - print("ERROR Decoding bearertoken") + print("ERROR Decoding bearertoken", flush=True) return False, self.token, None return False, None, None def is_authorized(self, role): if 'scope' in self.token_decoded is None: - print("ERROR Decoding bearertoken: No scope found") + print("ERROR Decoding Bearer token: No scope found", flush=True) return False scopes_token = self.token_decoded['scope'] if role in scopes_token: diff --git a/samples-python/datalayer.calc/.vscode/tasks.json b/samples-python/datalayer.calc/.vscode/tasks.json index 8ffed5be..6fe5bc49 100644 --- a/samples-python/datalayer.calc/.vscode/tasks.json +++ b/samples-python/datalayer.calc/.vscode/tasks.json @@ -1,48 +1,213 @@ { - // See https://go.microsoft.com/fwlink/?LinkId=733558 - // for the documentation about the tasks.json format - "version": "2.0.0", - "tasks": [ - { - "label": "0 Install venv and packages", - "type": "shell", - "command": "bash", - "args": ["install-venv.sh"], - "problemMatcher": [] - }, - { - "label": "build snap amd64", - "type": "shell", - "command": "bash", - "args": ["build-snap-amd64.sh"], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build snap arm64", - "type": "shell", - "command": "bash", - "args": ["build-snap-arm64.sh"], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - // https://snapcraft.io/docs/remote-build#heading--using - "label": "", - "type": "shell", - "command": "bash", - "args": ["build-snaps-remote.sh"], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - } - ] + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "Install venv", + "type": "shell", + "command": "bash", + "args": [ + "install-venv.sh" + ], + "problemMatcher": [] + }, + { + "label": "Build snap amd64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-amd64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build snap arm64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-arm64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + ], + "inputs": [ + { + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", + "type": "promptString", + "description": "IP address", + "default": "192.168.1.1" + }, + { + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", + "type": "promptString", + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" + }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" + } + ] } \ No newline at end of file diff --git a/samples-python/datalayer.calc/calculations/basic_arithmetic_operations.py b/samples-python/datalayer.calc/calculations/basic_arithmetic_operations.py index 7c1c06e6..24403b9b 100644 --- a/samples-python/datalayer.calc/calculations/basic_arithmetic_operations.py +++ b/samples-python/datalayer.calc/calculations/basic_arithmetic_operations.py @@ -92,7 +92,7 @@ def response_notify_callback(self, result: Result, items: typing.List[ctrlxdatal userdata: ctrlxdatalayer.clib.userData_c_void_p): if result != Result.OK: - print("response_notify_callback parameter result:", result) + print("response_notify_callback parameter result:", result, flush=True) self.out_error = True return @@ -103,7 +103,7 @@ def response_notify_callback(self, result: Result, items: typing.List[ctrlxdatal print("address:", item.get_address()) print("type:", item.get_data().get_type()) print("value:", item.get_data().get_float64()) - print("timestamp:", item.get_timestamp()) + print("timestamp:", item.get_timestamp(), flush=True) if item.get_address() == self.in1_address.get_string(): self.in1_value.close() # Avoid mem. leak @@ -155,10 +155,10 @@ def calc(self): print() print("Result ###################################") if self.out_error: - print("ERROR", self.out_error_text) + print("ERROR", self.out_error_text, flush=True) else: print(self.in1_value.get_float64(), self.mode.get_string(), - self.in2_value.get_float64(), "=", self.out.get_float64()) + self.in2_value.get_float64(), "=", self.out.get_float64(), flush=True) def calc_internal(self): @@ -215,15 +215,24 @@ def calc_internal(self): def register_node(self, name: str): address = self.addressRoot + name - print("Registering node", address) + print("Registering node", address, flush=True) self.provider.register_node( address, self.providerNode) def register_nodes(self): - self.register_node("in1") - self.register_node("in2") - self.register_node("mode") - self.register_node("out") + result = self.register_node("in1") + if result != ctrlxdatalayer.variant.Result.OK: + return result + + result = self.register_node("in2") + if result != ctrlxdatalayer.variant.Result.OK: + return result + + result = self.register_node("mode") + if result != ctrlxdatalayer.variant.Result.OK: + return result + + return self.register_node("out") def subscribe(self): @@ -235,11 +244,11 @@ def subscribe(self): addressList = [] address = self.in1_address.get_string() - print("Subscribing", address) + print("Subscribing", address, flush=True) addressList.append(address) address = self.in2_address.get_string() - print("Subscribing", address) + print("Subscribing", address, flush=True) addressList.append(address) result, self.subscription = self.client.create_subscription_sync( diff --git a/samples-python/datalayer.calc/calculations/convert.py b/samples-python/datalayer.calc/calculations/convert.py index 6f89be42..c6afb5a3 100644 --- a/samples-python/datalayer.calc/calculations/convert.py +++ b/samples-python/datalayer.calc/calculations/convert.py @@ -28,7 +28,7 @@ def get_float64(v: Variant): try: return Convert.get_float64_internal(v) except Exception as e: - print(e) + print(e, flush=True) return None diff --git a/samples-python/datalayer.calc/main.py b/samples-python/datalayer.calc/main.py index eaaea823..212f5251 100644 --- a/samples-python/datalayer.calc/main.py +++ b/samples-python/datalayer.calc/main.py @@ -49,7 +49,7 @@ def start_new_basic_arithmetic_operation( basicArithmeticOperation.unsubscribe() print("WARN Starting Data Layer subscriptions for", addr_root + "/" + id, "failed with: " + str(result)) - print("INFO Retry in 5s") + print("INFO Retry in 5s", flush=True) time.sleep(5.0) pass @@ -64,8 +64,7 @@ def start_new_basic_arithmetic_operation( print("- Provides result as Data Layer Node") print() print("Will be restarted by the snap system on error.") - print("===========================================================================") - print() + print("===========================================================================", flush=True) faulthandler.enable() @@ -76,31 +75,40 @@ def start_new_basic_arithmetic_operation( # Enter ip, user, password etc. if they differ from your application. client, client_connection_string = get_client(system) if client is None: - print("ERROR Could get ctrlX Datalayer client connection:", client_connection_string) + print("ERROR Could get ctrlX Datalayer client connection:", client_connection_string, flush=True) system.stop(False) sys.exit(1) - print("INFO ctrlX Datalayer client connection succeeded:", client_connection_string) + print("INFO ctrlX Datalayer client connection succeeded:", client_connection_string, flush=True) # Here default argument values are used: ip="192.168.1.1", user="boschrexroth", password="boschrexroth", ssl_port=443 # Enter ip, user, password etc. if they differ from your application. - provider, provider_connection_string = get_provider(system) + provider, provider_connection_string = get_provider(system, ip="10.52.244.109", + user="boschrexroth", + password="boschrexroth", + ssl_port=443) if provider is None: - print("ERROR Could get ctrlX Datalayer provider connection:", provider_connection_string) + print("ERROR Could get ctrlX Datalayer provider connection:", provider_connection_string, flush=True) provider.close() client.close() system.stop(False) sys.exit(2) - print("INFO ctrlX Datalayer provider connection succeeded:", provider_connection_string) + print("INFO ctrlX Datalayer provider connection succeeded:", provider_connection_string, flush=True) update_time = 1.0 bao = BasicArithmeticOperations( provider, client, addr_root, "1", "+", int(update_time)*1000) - bao.register_nodes() + result = bao.register_nodes() + if result != ctrlxdatalayer.variant.Result.OK: + print("ERROR Registering nodes failed with", str(result), flush=True) + provider.close() + client.close() + system.stop(False) + sys.exit(2) result = bao.subscribe() if result != ctrlxdatalayer.variant.Result.OK: - print("ERROR Subscribing values failed with", str(result)) + print("ERROR Subscribing values failed with", str(result), flush=True) provider.close() client.close() system.stop(False) @@ -119,7 +127,7 @@ def start_new_basic_arithmetic_operation( time.sleep(update_time) print("ERROR Client connection", client_connection_string, - "disconnected - exiting application. Will be restarted automatically.") + "disconnected - exiting application. Will be restarted automatically.", flush=True) bao.unsubscribe() provider.close() @@ -127,6 +135,6 @@ def start_new_basic_arithmetic_operation( # Attention: Doesn't return if any provider or client instance is still running stop_ok = system.stop(False) - print("System Stop", stop_ok) + print("System Stop", stop_ok, flush=True) sys.exit(3) diff --git a/samples-python/datalayer.client.browse/.vscode/tasks.json b/samples-python/datalayer.client.browse/.vscode/tasks.json index 72aaf14d..6fe5bc49 100644 --- a/samples-python/datalayer.client.browse/.vscode/tasks.json +++ b/samples-python/datalayer.client.browse/.vscode/tasks.json @@ -1,36 +1,213 @@ { - // See https://go.microsoft.com/fwlink/?LinkId=733558 - // for the documentation about the tasks.json format - "version": "2.0.0", - "tasks": [ - { - "label": "0 Install venv and packages", - "type": "shell", - "command": "bash", - "args": ["install-venv.sh"], - "problemMatcher": [] - }, - { - "label": "build snap amd64", - "type": "shell", - "command": "bash", - "args": ["build-snap-amd64.sh"], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build snap arm64", - "type": "shell", - "command": "bash", - "args": ["build-snap-arm64.sh"], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - } - ] + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "Install venv", + "type": "shell", + "command": "bash", + "args": [ + "install-venv.sh" + ], + "problemMatcher": [] + }, + { + "label": "Build snap amd64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-amd64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build snap arm64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-arm64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + ], + "inputs": [ + { + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", + "type": "promptString", + "description": "IP address", + "default": "192.168.1.1" + }, + { + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", + "type": "promptString", + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" + }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" + } + ] } \ No newline at end of file diff --git a/samples-python/datalayer.client.browse/main.py b/samples-python/datalayer.client.browse/main.py index 74f0b50c..ecd602ed 100644 --- a/samples-python/datalayer.client.browse/main.py +++ b/samples-python/datalayer.client.browse/main.py @@ -40,7 +40,7 @@ def main(): datalayer_client, datalayer_client_connection_string = get_client( datalayer_system) if datalayer_client is None: - print("ERROR Connecting", datalayer_client_connection_string, "failed.") + print("ERROR Connecting", datalayer_client_connection_string, "failed.", flush=True) sys.exit(1) with datalayer_client: # datalayer_client is closed automatically when leaving with block @@ -49,17 +49,17 @@ def main(): if datalayer_client.is_connected() is False: print("ERROR Not connected to", datalayer_client_connection_string, - "- restarting app after a delay of 10 s ...") + "- restarting app after a delay of 10 s ...", flush=True) sys.exit(2) # Browse the whole ctrlX Data Layer tree - print("Browsing and reading nodes...") + print("Browsing and reading nodes...", flush=True) browse_tree(datalayer_client, datalayer_system.json_converter()) - print("Stopping Datalayer System") + print("Stopping Data Layer System", flush=True) # Attention: Doesn't return if any provider or client instance is still running stop_ok = datalayer_system.stop(False) - print("System Stop", stop_ok) + print("System Stop", stop_ok, flush=True) def browse_tree(client: ctrlxdatalayer.client.Client, converter: ctrlxdatalayer.system.Converter, address=""): @@ -67,14 +67,14 @@ def browse_tree(client: ctrlxdatalayer.client.Client, converter: ctrlxdatalayer. # print current address and get value of node node_value = get_value(client, converter, address) if node_value is None: - print(address) + print(address, flush=True) else: - print(address, node_value) + print(address, node_value, flush=True) # Browse Data Layer tree result, data = client.browse_sync(address) if result != Result.OK: - print("ERROR Browsing Data Layer failed with: ", result) + print("ERROR Browsing Data Layer failed with: ", result, flush=True) return with data: # Recursive loop @@ -88,7 +88,7 @@ def get_value(client: ctrlxdatalayer.client.Client, converter: ctrlxdatalayer.sy # get data with read sync result, data = client.read_sync(address) if result != Result.OK: - # print("ERROR Reading Data Layer failed with: ", result) + # print("ERROR Reading Data Layer failed with: ", result, flush=True) return with data: @@ -138,20 +138,20 @@ def get_value(client: ctrlxdatalayer.client.Client, converter: ctrlxdatalayer.sy # Get type address for flatbuffers information typeAddress = get_typeaddress(client, address) if typeAddress is None: - print("ERROR Type Address is none") + print("ERROR Type Address is none", flush=True) return # Read type address as variant result, typeVar = client.read_sync(typeAddress) if result != Result.OK: - print("ERROR Reading Type Value failed with: ", result) + print("ERROR Reading Type Value failed with: ", result, flush=True) return # Convert variant flatbuffers data to json type result, json = converter.converter_generate_json_complex( data, typeVar, -1) if result != Result.OK: - print("ERROR Converting json failed with: ", result) + print("ERROR Converting json failed with: ", result, flush=True) return return json.get_string() @@ -189,7 +189,7 @@ def get_value(client: ctrlxdatalayer.client.Client, converter: ctrlxdatalayer.sy if vt == VariantType.UINT8: return data.get_uint8() - print("WARNING Unknown Variant Type:", vt) + print("WARNING Unknown Variant Type:", vt, flush=True) return None @@ -197,14 +197,14 @@ def get_typeaddress(client: ctrlxdatalayer.client.Client, address: str): result, metadata = client.metadata_sync(address) if result != Result.OK: - print("ERROR Reading metadata of ", address, " failed with: ", result) + print("ERROR Reading metadata of ", address, " failed with: ", result, flush=True) return metadata_root = Metadata.Metadata.GetRootAsMetadata( metadata.get_flatbuffers()) if metadata_root.ReferencesLength() == 0: - print("ERROR Metadata references are empty") + print("ERROR Metadata references are empty", flush=True) return for i in range(0, metadata_root.ReferencesLength()): diff --git a/samples-python/datalayer.client.bulk/.vscode/tasks.json b/samples-python/datalayer.client.bulk/.vscode/tasks.json index 72aaf14d..6fe5bc49 100644 --- a/samples-python/datalayer.client.bulk/.vscode/tasks.json +++ b/samples-python/datalayer.client.bulk/.vscode/tasks.json @@ -1,36 +1,213 @@ { - // See https://go.microsoft.com/fwlink/?LinkId=733558 - // for the documentation about the tasks.json format - "version": "2.0.0", - "tasks": [ - { - "label": "0 Install venv and packages", - "type": "shell", - "command": "bash", - "args": ["install-venv.sh"], - "problemMatcher": [] - }, - { - "label": "build snap amd64", - "type": "shell", - "command": "bash", - "args": ["build-snap-amd64.sh"], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build snap arm64", - "type": "shell", - "command": "bash", - "args": ["build-snap-arm64.sh"], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - } - ] + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "Install venv", + "type": "shell", + "command": "bash", + "args": [ + "install-venv.sh" + ], + "problemMatcher": [] + }, + { + "label": "Build snap amd64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-amd64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build snap arm64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-arm64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + ], + "inputs": [ + { + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", + "type": "promptString", + "description": "IP address", + "default": "192.168.1.1" + }, + { + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", + "type": "promptString", + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" + }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" + } + ] } \ No newline at end of file diff --git a/samples-python/datalayer.client.light/.vscode/tasks.json b/samples-python/datalayer.client.light/.vscode/tasks.json index 72aaf14d..6fe5bc49 100644 --- a/samples-python/datalayer.client.light/.vscode/tasks.json +++ b/samples-python/datalayer.client.light/.vscode/tasks.json @@ -1,36 +1,213 @@ { - // See https://go.microsoft.com/fwlink/?LinkId=733558 - // for the documentation about the tasks.json format - "version": "2.0.0", - "tasks": [ - { - "label": "0 Install venv and packages", - "type": "shell", - "command": "bash", - "args": ["install-venv.sh"], - "problemMatcher": [] - }, - { - "label": "build snap amd64", - "type": "shell", - "command": "bash", - "args": ["build-snap-amd64.sh"], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build snap arm64", - "type": "shell", - "command": "bash", - "args": ["build-snap-arm64.sh"], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - } - ] + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "Install venv", + "type": "shell", + "command": "bash", + "args": [ + "install-venv.sh" + ], + "problemMatcher": [] + }, + { + "label": "Build snap amd64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-amd64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build snap arm64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-arm64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + ], + "inputs": [ + { + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", + "type": "promptString", + "description": "IP address", + "default": "192.168.1.1" + }, + { + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", + "type": "promptString", + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" + }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" + } + ] } \ No newline at end of file diff --git a/samples-python/datalayer.client.light/main.py b/samples-python/datalayer.client.light/main.py index 01eb1bcd..e0d269dd 100644 --- a/samples-python/datalayer.client.light/main.py +++ b/samples-python/datalayer.client.light/main.py @@ -39,20 +39,20 @@ def main(): print() print("=================================================================") print("sdk-py-datalayer-client - A ctrlX Data Layer Client App in Python") - print("=================================================================") + print("=================================================================", flush=True) with ctrlxdatalayer.system.System("") as datalayer_system: datalayer_system.start(False) datalayer_client, datalayer_client_connection_string = get_client(datalayer_system, ip="10.0.2.2", ssl_port=8443) if datalayer_client is None: - print("ERROR Connecting", datalayer_client_connection_string, "failed.") + print("ERROR Connecting", datalayer_client_connection_string, "failed.", flush=True) sys.exit(1) with datalayer_client: # datalayer_client is closed automatically when leaving with block if datalayer_client.is_connected() is False: - print("ERROR Data Layer is NOT connected:", datalayer_client_connection_string) + print("ERROR Data Layer is NOT connected:", datalayer_client_connection_string, flush=True) sys.exit(2) @@ -70,17 +70,17 @@ def main(): sub_prop.set_flatbuffers(builder.Output()) # Create subscription - print("INFO Creating subscription") + print("INFO Creating subscription", flush=True) result, sub = datalayer_client.create_subscription_sync(sub_prop, cb_subscription_sync) if result is not Result.OK: - print("ERROR Creating subscription failed:", result) + print("ERROR Creating subscription failed:", result, flush=True) # Add subscription node - print("INFO Add subscription node") + print("INFO Add subscription node", flush=True) sub_adr = "framework/metrics/system/cpu-utilisation-percent" result = sub.subscribe(sub_adr) if result is not Result.OK: - print("ERROR Adding subscription node failed:", result) + print("ERROR Adding subscription node failed:", result, flush=True) while datalayer_client.is_connected(): @@ -90,7 +90,7 @@ def main(): addr = "framework/metrics/system/memused-percent" result, float64_var = datalayer_client.read_sync(addr) float64_value = float64_var.get_float64() - print("INFO %s Sync read '%s': %f" % (dt_str, addr, float64_value)) + print("INFO %s Sync read '%s': %f" % (dt_str, addr, float64_value), flush=True) # Flatbuffers --------------------------------------------------- addr = "datalayer/subscriptions/settings" @@ -114,29 +114,29 @@ def main(): result, json = datalayer_system.json_converter().converter_generate_json_complex(fbs_var, type_var, -1) fbs_value = json.get_string() - print("INFO %s Sync read '%s': %s" % (dt_str, addr, fbs_value)) + print("INFO %s Sync read '%s': %s" % (dt_str, addr, fbs_value), flush=True) time.sleep(2.0) print("ERROR Data Layer is NOT connected") - print("INFO Closing subscription") + print("INFO Closing subscription", flush=True) sub.close() stop_ok = datalayer_system.stop(False) # Attention: Doesn't return if any provider or client instance is still running - print("System Stop", stop_ok) + print("System Stop", stop_ok, flush=True) # Response notify callback function def cb_subscription_sync(result: Result, items: List[ctrlxdatalayer.subscription.NotifyItem], userdata): if result is not Result.OK: - print("ERROR notify subscription:", result) + print("ERROR notify subscription:", result, flush=True) return timestamp = items[0].get_timestamp() dt = datetime.fromtimestamp(timestamp/10000000-11644473600) # convert ldap to unix timestamp dt_str = dt.strftime("%d/%m/%Y %H:%M:%S.%f") address = items[0].get_address() val = Variant.get_float64(items[0].get_data()) - print("INFO %s Subscription notification '%s': %f" % (dt_str, address, val)) + print("INFO %s Subscription notification '%s': %f" % (dt_str, address, val), flush=True) if __name__ == '__main__': diff --git a/samples-python/datalayer.client.sub/.vscode/tasks.json b/samples-python/datalayer.client.sub/.vscode/tasks.json index 72aaf14d..6fe5bc49 100644 --- a/samples-python/datalayer.client.sub/.vscode/tasks.json +++ b/samples-python/datalayer.client.sub/.vscode/tasks.json @@ -1,36 +1,213 @@ { - // See https://go.microsoft.com/fwlink/?LinkId=733558 - // for the documentation about the tasks.json format - "version": "2.0.0", - "tasks": [ - { - "label": "0 Install venv and packages", - "type": "shell", - "command": "bash", - "args": ["install-venv.sh"], - "problemMatcher": [] - }, - { - "label": "build snap amd64", - "type": "shell", - "command": "bash", - "args": ["build-snap-amd64.sh"], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build snap arm64", - "type": "shell", - "command": "bash", - "args": ["build-snap-arm64.sh"], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - } - ] + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "Install venv", + "type": "shell", + "command": "bash", + "args": [ + "install-venv.sh" + ], + "problemMatcher": [] + }, + { + "label": "Build snap amd64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-amd64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build snap arm64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-arm64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + ], + "inputs": [ + { + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", + "type": "promptString", + "description": "IP address", + "default": "192.168.1.1" + }, + { + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", + "type": "promptString", + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" + }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" + } + ] } \ No newline at end of file diff --git a/samples-python/datalayer.client.sub/datalayerclient/app.py b/samples-python/datalayer.client.sub/datalayerclient/app.py index 3edef771..1d8c6389 100644 --- a/samples-python/datalayer.client.sub/datalayerclient/app.py +++ b/samples-python/datalayer.client.sub/datalayerclient/app.py @@ -34,15 +34,15 @@ def rncb(result: Result, items: typing.List[ctrlxdatalayer.subscription.NotifyIt now = datetime.now().time() print(now, "----------------------------------------------------------") - print("ResponseNotifyCallback", result) + print("ResponseNotifyCallback", result, flush=True) if result != Result.OK: return if items is None: - print("No items") + print("No items", flush=True) return - print("Number of items", len(items)) + print("Number of items", len(items), flush=True) if len(items) <= 0: return @@ -54,22 +54,22 @@ def rncb(result: Result, items: typing.List[ctrlxdatalayer.subscription.NotifyIt print(" value:", item.get_data().get_float32()) print(" timestamp:", item.get_timestamp()) print(" datetime:", ctrlxdatalayer.subscription.to_datetime( - item.get_timestamp())) + item.get_timestamp()), flush=True) n = n + 1 def subscribe_single(client: Client, subscription_properties: Variant): - print("subscribe_single() +++++++++++++++++++++++++++++++++++++++++++++++") + print("subscribe_single() +++++++++++++++++++++++++++++++++++++++++++++++", flush=True) result, subscription = client.create_subscription_sync( subscription_properties, rncb) if result != Result.OK: - print("ERROR create_subscription_sync() failed with:", result) + print("ERROR create_subscription_sync() failed with:", result, flush=True) return result, None if subscription is None: - print("ERROR create_subscription_sync() returned: None") + print("ERROR create_subscription_sync() returned: None", flush=True) return Result.CREATION_FAILED, None address = "framework/metrics/system/cpu-utilisation-percent" @@ -96,21 +96,21 @@ def get_address_list(client: Client, addressBase: str): def subscribe_multi(client: Client, subscription_properties: Variant): - print("subscribe_multi() ++++++++++++++++++++++++++++++++++++++++++++++++") + print("subscribe_multi() ++++++++++++++++++++++++++++++++++++++++++++++++", flush=True) addressBase = "framework/metrics/system/" addressList = get_address_list(client, addressBase) if addressList is None: - print("ERROR No sub nodes found:", addressBase) + print("ERROR No sub nodes found:", addressBase, flush=True) return Result.FAILED, None result, subscription = client.create_subscription_sync(subscription_properties, rncb) if result != Result.OK: - print("ERROR create_subscription_sync() failed with:", result) + print("ERROR create_subscription_sync() failed with:", result, flush=True) return result, None if subscription is None: - print("ERROR create_subscription_sync() returned: None") + print("ERROR create_subscription_sync() returned: None", flush=True) return Result.CREATION_FAILED, None result = subscription.subscribe_multi(addressList) diff --git a/samples-python/datalayer.client.sub/main.py b/samples-python/datalayer.client.sub/main.py index f04e9dda..000d19a2 100644 --- a/samples-python/datalayer.client.sub/main.py +++ b/samples-python/datalayer.client.sub/main.py @@ -40,8 +40,7 @@ print("=============================================================================") print("Simple ctrlX Data Layer Client Snap in Python using Data Layer subscriptions.") print("Will be restarted by the snap system.") - print("=============================================================================") - print() + print("=============================================================================", flush=True) faulthandler.enable() @@ -50,7 +49,7 @@ datalayer_client, datalayer_client_connection_string = get_client(datalayer_system) if datalayer_client is None: - print("WARNING Connecting", datalayer_client_connection_string, "failed.") + print("WARNING Connecting", datalayer_client_connection_string, "failed.", flush=True) sys.exit(1) with datalayer_client: # datalayer_client is closed automatically when leaving with block @@ -59,18 +58,18 @@ "python-datalayer-client-sub", publish_interval=100) if subscription_properties is None: - print("ERROR create_properties() returned: None") + print("ERROR create_properties() returned: None", flush=True) sys.exit(1) with subscription_properties: result, subscription = datalayerclient.app.subscribe_single( datalayer_client, subscription_properties) if result != Result.OK: - print("ERROR subscribe_single() failed with:", result) + print("ERROR subscribe_single() failed with:", result, flush=True) sys.exit(1) if subscription is None: - print("ERROR subscribe_single() returned None") + print("ERROR subscribe_single() returned None", flush=True) sys.exit(1) with subscription: @@ -80,11 +79,11 @@ result, subscription = datalayerclient.app.subscribe_multi( datalayer_client, subscription_properties) if result != Result.OK: - print("ERROR subscribe_multi() failed with:", result) + print("ERROR subscribe_multi() failed with:", result, flush=True) sys.exit(1) if subscription is None: - print("ERROR subscribe_multi() returned None") + print("ERROR subscribe_multi() returned None", flush=True) sys.exit(1) with subscription: @@ -97,6 +96,6 @@ # Attention: Doesn't return if any provider or client instance is still running stop_ok = datalayer_system.stop(False) - print("System Stop", stop_ok) + print("System Stop", stop_ok, flush=True) sys.exit(0) diff --git a/samples-python/datalayer.client/.vscode/tasks.json b/samples-python/datalayer.client/.vscode/tasks.json index 72aaf14d..6fe5bc49 100644 --- a/samples-python/datalayer.client/.vscode/tasks.json +++ b/samples-python/datalayer.client/.vscode/tasks.json @@ -1,36 +1,213 @@ { - // See https://go.microsoft.com/fwlink/?LinkId=733558 - // for the documentation about the tasks.json format - "version": "2.0.0", - "tasks": [ - { - "label": "0 Install venv and packages", - "type": "shell", - "command": "bash", - "args": ["install-venv.sh"], - "problemMatcher": [] - }, - { - "label": "build snap amd64", - "type": "shell", - "command": "bash", - "args": ["build-snap-amd64.sh"], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build snap arm64", - "type": "shell", - "command": "bash", - "args": ["build-snap-arm64.sh"], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - } - ] + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "Install venv", + "type": "shell", + "command": "bash", + "args": [ + "install-venv.sh" + ], + "problemMatcher": [] + }, + { + "label": "Build snap amd64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-amd64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build snap arm64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-arm64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + ], + "inputs": [ + { + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", + "type": "promptString", + "description": "IP address", + "default": "192.168.1.1" + }, + { + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", + "type": "promptString", + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" + }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" + } + ] } \ No newline at end of file diff --git a/samples-python/datalayer.client/app/call_datalayer_client.py b/samples-python/datalayer.client/app/call_datalayer_client.py index 948473c5..1e06cacf 100644 --- a/samples-python/datalayer.client/app/call_datalayer_client.py +++ b/samples-python/datalayer.client/app/call_datalayer_client.py @@ -136,109 +136,109 @@ def print_data(self, msg: str, result: Result, address: str, data: Variant): if result != Result.OK: return - print(msg, address, result, " ", end='') + print(msg, address, result, " ", end='', flush=True) if data.get_type() == VariantType.ARRAY_BOOL8: - print(data.get_array_bool8()) + print(data.get_array_bool8(), flush=True) return if data.get_type() == VariantType.ARRAY_FLOAT32: - print(data.get_array_float32()) + print(data.get_array_float32(), flush=True) return if data.get_type() == VariantType.ARRAY_FLOAT64: - print(data.get_array_float64()) + print(data.get_array_float64(), flush=True) return if data.get_type() == VariantType.ARRAY_INT16: - print(data.get_array_int16()) + print(data.get_array_int16(), flush=True) return if data.get_type() == VariantType.ARRAY_INT32: - print(data.get_array_int32()) + print(data.get_array_int32(), flush=True) return if data.get_type() == VariantType.ARRAY_INT64: - print(data.get_array_int64()) + print(data.get_array_int64(), flush=True) return if data.get_type() == VariantType.ARRAY_INT8: - print(data.get_array_int8()) + print(data.get_array_int8(), flush=True) return if data.get_type() == VariantType.ARRAY_STRING: - print(data.get_array_bool8()) + print(data.get_array_bool8(), flush=True) return if data.get_type() == VariantType.ARRAY_UINT16: - print(data.get_array_uint16()) + print(data.get_array_uint16(), flush=True) return if data.get_type() == VariantType.ARRAY_UINT32: - print(data.get_array_uint32()) + print(data.get_array_uint32(), flush=True) return if data.get_type() == VariantType.ARRAY_UINT64: - print(data.get_array_uint64()) + print(data.get_array_uint64(), flush=True) return if data.get_type() == VariantType.ARRAY_UINT8: - print(data.get_array_uint8()) + print(data.get_array_uint8(), flush=True) return if data.get_type() == VariantType.BOOL8: - print(data.get_bool8()) + print(data.get_bool8(), flush=True) return if data.get_type() == VariantType.FLATBUFFERS: - print(data.get_flatbuffers()) + print(data.get_flatbuffers(), flush=True) return if data.get_type() == VariantType.FLOAT32: - print(data.get_float32()) + print(data.get_float32(), flush=True) return if data.get_type() == VariantType.FLOAT64: - print(data.get_float64()) + print(data.get_float64(), flush=True) return if data.get_type() == VariantType.INT16: - print(data.get_int16()) + print(data.get_int16(), flush=True) return if data.get_type() == VariantType.INT32: - print(data.get_int32()) + print(data.get_int32(), flush=True) return if data.get_type() == VariantType.INT64: - print(data.get_int64()) + print(data.get_int64(), flush=True) return if data.get_type() == VariantType.INT8: - print(data.get_int8()) + print(data.get_int8(), flush=True) return if data.get_type() == VariantType.STRING: - print(data.get_string()) + print(data.get_string(), flush=True) return if data.get_type() == VariantType.UINT16: - print(data.get_uint16()) + print(data.get_uint16(), flush=True) return if data.get_type() == VariantType.UINT32: - print(data.get_uint32()) + print(data.get_uint32(), flush=True) return if data.get_type() == VariantType.UINT64: - print(data.get_uint64()) + print(data.get_uint64(), flush=True) return if data.get_type() == VariantType.UINT8: - print(data.get_uint8()) + print(data.get_uint8(), flush=True) return - print("UNHANDLED ---------") + print("UNHANDLED ---------", flush=True) def read(self): @@ -530,7 +530,7 @@ def print_metadata(self, text: str, result: Result, data: Variant): "create=", allowedoperations.Create(), "delete=", allowedoperations.Delete(), "metadata.DisplayName()", metadata.DisplayName(), - "metadata.DisplayFormat()", metadata.DisplayFormat()) + "metadata.DisplayFormat()", metadata.DisplayFormat(), flush=True) def metadata_async_callback(self, result: Result, data: Variant, userdata: ctrlxdatalayer.clib.userData_c_void_p): self.waiting_for = None diff --git a/samples-python/datalayer.client/main.py b/samples-python/datalayer.client/main.py index 1a51fbf1..0bb641d0 100644 --- a/samples-python/datalayer.client/main.py +++ b/samples-python/datalayer.client/main.py @@ -38,7 +38,7 @@ def handler(signum, frame): global close_app close_app = True -# print('Here you go signum: ', signum, close_app) + # print('Here you go signum: ', signum, close_app, flush=True) if __name__ == '__main__': @@ -64,33 +64,32 @@ def handler(signum, frame): print("Precondition:") print("Build and install the snap 'sdk-cpp-alldata' from the SDK folder") print("samples-cpp/datalayer.provider.all-data") - print("========================================================================") - print() + print("========================================================================", flush=True) with ctrlxdatalayer.system.System("") as datalayer_system: - print("INFO Starting Data Layer system") + print("INFO Starting Data Layer system", flush=True) datalayer_system.start(False) datalayer_client, connection_string = get_client(datalayer_system) if datalayer_client is None: - print("WARNING Connecting", connection_string, "failed.") + print("WARNING Connecting", connection_string, "failed.", flush=True) datalayer_system.stop(False) sys.exit(1) - print("INFO Connecting", connection_string, "succeeded.") + print("INFO Connecting", connection_string, "succeeded.", flush=True) with datalayer_client: # datalayer_client is closed automatically when leaving with block - print("INFO Creating Python Data Layer Client instance") + print("INFO Creating Python Data Layer Client instance", flush=True) calldatalayerclient = CallDataLayerClient(datalayer_client) while datalayer_client.is_connected() and not close_app: calldatalayerclient.run() time.sleep(1.0) - print("ERROR Data Layer is NOT connected") + print("ERROR Data Layer is NOT connected", flush=True) print("INFO Stopping Data Layer system") # Attention: Doesn't return if any provider or client instance is still runnning stop_ok = datalayer_system.stop(False) - print("System Stop", stop_ok) + print("System Stop", stop_ok, flush=True) diff --git a/samples-python/datalayer.provider.all-data/.vscode/tasks.json b/samples-python/datalayer.provider.all-data/.vscode/tasks.json index 72aaf14d..6fe5bc49 100644 --- a/samples-python/datalayer.provider.all-data/.vscode/tasks.json +++ b/samples-python/datalayer.provider.all-data/.vscode/tasks.json @@ -1,36 +1,213 @@ { - // See https://go.microsoft.com/fwlink/?LinkId=733558 - // for the documentation about the tasks.json format - "version": "2.0.0", - "tasks": [ - { - "label": "0 Install venv and packages", - "type": "shell", - "command": "bash", - "args": ["install-venv.sh"], - "problemMatcher": [] - }, - { - "label": "build snap amd64", - "type": "shell", - "command": "bash", - "args": ["build-snap-amd64.sh"], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build snap arm64", - "type": "shell", - "command": "bash", - "args": ["build-snap-arm64.sh"], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - } - ] + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "Install venv", + "type": "shell", + "command": "bash", + "args": [ + "install-venv.sh" + ], + "problemMatcher": [] + }, + { + "label": "Build snap amd64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-amd64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build snap arm64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-arm64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + ], + "inputs": [ + { + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", + "type": "promptString", + "description": "IP address", + "default": "192.168.1.1" + }, + { + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", + "type": "promptString", + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" + }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" + } + ] } \ No newline at end of file diff --git a/samples-python/datalayer.provider.all-data/alldataprovider/nodeManagerAllData.py b/samples-python/datalayer.provider.all-data/alldataprovider/nodeManagerAllData.py index 937ef528..91cadf79 100644 --- a/samples-python/datalayer.provider.all-data/alldataprovider/nodeManagerAllData.py +++ b/samples-python/datalayer.provider.all-data/alldataprovider/nodeManagerAllData.py @@ -178,7 +178,7 @@ def create_nodes(self, address: str, dynamic: bool): def create_single_node(self, addressBranch: str, addressType : str, name: str, unit: str, description: str, dynamic: bool, data: Variant): address = addressBranch + name - print("Creating", address) + print("Creating", address, flush=True) if is_blank(addressType): addressType = "types/datalayer/" + name diff --git a/samples-python/datalayer.provider.all-data/alldataprovider/providerNodeAllData.py b/samples-python/datalayer.provider.all-data/alldataprovider/providerNodeAllData.py index 04eec6e4..5c553dba 100644 --- a/samples-python/datalayer.provider.all-data/alldataprovider/providerNodeAllData.py +++ b/samples-python/datalayer.provider.all-data/alldataprovider/providerNodeAllData.py @@ -63,39 +63,39 @@ def __init__(self, type_path=addressType) def __on_create(self, userdata: ctrlxdatalayer.clib.userData_c_void_p, address: str, data: Variant, cb: NodeCallback): - # print("__on_create", address) + # print("__on_create", address, flush=True) cb(Result.OK, None) def __on_remove(self, userdata: ctrlxdatalayer.clib.userData_c_void_p, address: str, cb: NodeCallback): # Not implemented because no wildcard is registered - print("__on_remove", address) + print("__on_remove", address, flush=True) cb(Result.UNSUPPORTED, None) def __on_browse(self, userdata: ctrlxdatalayer.clib.userData_c_void_p, address: str, cb: NodeCallback): - # print("__on_browse", address) + # print("__on_browse", address, flush=True) cb(Result.OK, None) def __on_read(self, userdata: ctrlxdatalayer.clib.userData_c_void_p, address: str, data: Variant, cb: NodeCallback): - # print("__on_read", address) - this command slows the performance down + # print("__on_read", address, flush=True) - this command slows the performance down new_data = self.data cb(Result.OK, new_data) def __on_write(self, userdata: ctrlxdatalayer.clib.userData_c_void_p, address: str, data: Variant, cb: NodeCallback): if self.dynamic is False: - print("__on_write PERMISSION_DENIED", address, data.get_type()) + print("__on_write PERMISSION_DENIED", address, data.get_type(), flush=True) cb(Result.PERMISSION_DENIED, None) return if self.data.get_type() != data.get_type(): - print("__on_write TYPE_MISMATCH", address, data.get_type()) + print("__on_write TYPE_MISMATCH", address, data.get_type(), flush=True) cb(Result.TYPE_MISMATCH, None) return - print("__on_write", address, data.get_type()) + print("__on_write", address, data.get_type(), flush=True) _, self.data = data.clone() cb(Result.OK, data) def __on_metadata(self, userdata: ctrlxdatalayer.clib.userData_c_void_p, address: str, cb: NodeCallback): - # print("__on_metadata", address) + # print("__on_metadata", address, flush=True) cb(Result.OK, self.metadata) diff --git a/samples-python/datalayer.provider.all-data/main.py b/samples-python/datalayer.provider.all-data/main.py index 7de0747a..8c728776 100644 --- a/samples-python/datalayer.provider.all-data/main.py +++ b/samples-python/datalayer.provider.all-data/main.py @@ -39,7 +39,7 @@ def handler(signum, frame): global close_app close_app = True -# print('Here you go signum: ', signum, close_app) + #print('Here you go signum: ', signum, close_app, flush=True) def main(): @@ -54,11 +54,11 @@ def main(): # Try SSL port 8443 provider, connection_string = get_provider(datalayer_system) if provider is None: - print("ERROR Connecting", connection_string, "failed.") + print("ERROR Connecting", connection_string, "failed.", flush=True) datalayer_system.stop(False) sys.exit(1) - print("INFO Connecting", connection_string, "succeeded.") + print("INFO Connecting", connection_string, "succeeded.", flush=True) with provider: # provider.close() is called automatically when leaving with block @@ -70,13 +70,13 @@ def main(): while provider.is_connected() and not close_app: time.sleep(5.0) - print("ERROR: Data Layer provider is NOT connected") + print("ERROR: Data Layer provider is NOT connected", flush=True) provider.stop() # Attention: Doesn't return if any provider or client instance is still running stop_ok = datalayer_system.stop(False) - print("System Stop", stop_ok) + print("System Stop", stop_ok, flush=True) if __name__ == "__main__": diff --git a/samples-python/datalayer.provider/.vscode/tasks.json b/samples-python/datalayer.provider/.vscode/tasks.json index cd7717d8..32472b3a 100644 --- a/samples-python/datalayer.provider/.vscode/tasks.json +++ b/samples-python/datalayer.provider/.vscode/tasks.json @@ -1,43 +1,222 @@ { - // See https://go.microsoft.com/fwlink/?LinkId=733558 - // for the documentation about the tasks.json format - "version": "2.0.0", - "tasks": [ - { - "label": "Install venv and requirements", - "type": "shell", - "command": "bash", - "args": ["install-venv.sh"], - "problemMatcher": [] - }, - { - "label": "make bfbs mddb", - "type": "shell", - "command": "bash", - "args": ["make-bfbs-mddb.sh"], - "problemMatcher": [] - }, - { - "label": "build snap amd64", - "type": "shell", - "command": "bash", - "args": ["build-snap-amd64.sh"], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build snap arm64", - "type": "shell", - "command": "bash", - "args": ["build-snap-arm64.sh"], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - } - ] + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "Install venv", + "type": "shell", + "command": "bash", + "args": [ + "install-venv.sh" + ], + "problemMatcher": [] + }, + { + "label": "Make bfbs mddb", + "type": "shell", + "command": "bash", + "args": [ + "make-bfbs-mddb.sh" + ], + "problemMatcher": [] + }, + { + "label": "Build snap amd64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-amd64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build snap arm64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-arm64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + ], + "inputs": [ + { + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", + "type": "promptString", + "description": "IP address", + "default": "192.168.1.1" + }, + { + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", + "type": "promptString", + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" + }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" + } + ] } \ No newline at end of file diff --git a/samples-python/datalayer.provider/app/my_provider_node.py b/samples-python/datalayer.provider/app/my_provider_node.py index a12bc6ab..8b127910 100644 --- a/samples-python/datalayer.provider/app/my_provider_node.py +++ b/samples-python/datalayer.provider/app/my_provider_node.py @@ -58,28 +58,28 @@ def set_value(self, value: Variant): self.data = value def __on_create(self, userdata: ctrlxdatalayer.clib.userData_c_void_p, address: str, data: Variant, cb: NodeCallback): - print("__on_create()", "address:", address, "userdata:", userdata) + print("__on_create()", "address:", address, "userdata:", userdata, flush=True) cb(Result.OK, data) def __on_remove(self, userdata: ctrlxdatalayer.clib.userData_c_void_p, address: str, cb: NodeCallback): - print("__on_remove()", "address:", address, "userdata:", userdata) + print("__on_remove()", "address:", address, "userdata:", userdata, flush=True) cb(Result.UNSUPPORTED, None) def __on_browse(self, userdata: ctrlxdatalayer.clib.userData_c_void_p, address: str, cb: NodeCallback): - print("__on_browse()", "address:", address, "userdata:", userdata) + print("__on_browse()", "address:", address, "userdata:", userdata, flush=True) new_data = Variant() new_data.set_array_string([]) cb(Result.OK, new_data) def __on_read(self, userdata: ctrlxdatalayer.clib.userData_c_void_p, address: str, data: Variant, cb: NodeCallback): print("__on_read()", "address:", address, - "data:", self.data, "userdata:", userdata) + "data:", self.data, "userdata:", userdata, flush=True) new_data = self.data cb(Result.OK, new_data) def __on_write(self, userdata: ctrlxdatalayer.clib.userData_c_void_p, address: str, data: Variant, cb: NodeCallback): print("__on_write()", "address:", address, - "data:", data, "userdata:", userdata) + "data:", data, "userdata:", userdata, flush=True) if self.data.get_type() != data.get_type(): cb(Result.TYPE_MISMATCH, None) @@ -89,5 +89,5 @@ def __on_write(self, userdata: ctrlxdatalayer.clib.userData_c_void_p, address: s cb(Result.OK, self.data) def __on_metadata(self, userdata: ctrlxdatalayer.clib.userData_c_void_p, address: str, cb: NodeCallback): - print("__on_metadata()", "address:", address) + print("__on_metadata()", "address:", address, flush=True) cb(Result.FAILED, None) # Take metadata from metadata.mddb diff --git a/samples-python/datalayer.provider/main.py b/samples-python/datalayer.provider/main.py index 397f8d18..5559eb15 100644 --- a/samples-python/datalayer.provider/main.py +++ b/samples-python/datalayer.provider/main.py @@ -56,17 +56,16 @@ def main(): datalayer_system.start(False) # ip="10.0.2.2", ssl_port=8443: ctrlX virtual with port forwarding and default port mapping - provider, connection_string = get_provider( - datalayer_system, ip="10.0.2.2", ssl_port=8443) + provider, connection_string = get_provider(datalayer_system) if provider is None: - print("ERROR Connecting", connection_string, "failed.") + print("ERROR Connecting", connection_string, "failed.", flush=True) sys.exit(1) with provider: # provider.close() is called automatically when leaving with... block result = provider.start() if result != Result.OK: - print("ERROR Starting Data Layer Provider failed with:", result) + print("ERROR Starting Data Layer Provider failed with:", result, flush=True) return # Path to compiled files @@ -87,23 +86,23 @@ def main(): result = provider.register_type(type_sampleSchema_inertialValue, bfbs_path) if result != Result.OK: print("WARNING Registering", - type_sampleSchema_inertialValue, "failed with:", result) + type_sampleSchema_inertialValue, "failed with:", result, flush=True) # Register Metadata Database result = provider.register_type("datalayer", mddb_path) if result != Result.OK: print("WARNING Registering", - mddb_path, "failed with:", result) + mddb_path, "failed with:", result, flush=True) # Create nodes provider_node_fbs = provide_fbs(provider, "inertial-value") provider_node_str = provide_string(provider, "string-value") - print("INFO Running endless loop...") + print("INFO Running endless loop...", flush=True) while provider.is_connected(): time.sleep(1.0) # Seconds - print("ERROR Data Layer Provider is disconnected") + print("ERROR Data Layer Provider is disconnected", flush=True) provider_node_fbs.unregister_node() del provider_node_fbs @@ -111,17 +110,17 @@ def main(): provider_node_str.unregister_node() del provider_node_str - print("Unregistering", type_sampleSchema_inertialValue, end=" ") + print("Unregistering", type_sampleSchema_inertialValue, end=" ", flush=True) result = provider.unregister_type(type_sampleSchema_inertialValue) - print(result) + print(result, flush=True) - print("Stopping Data Layer provider:", end=" ") + print("Stopping Data Layer provider:", end=" ", flush=True) result = provider.stop() - print(result) + print(result, flush=True) # Attention: Doesn't return if any provider or client instance is still running stop_ok = datalayer_system.stop(False) - print("System Stop", stop_ok) + print("System Stop", stop_ok, flush=True) def provide_fbs(provider: ctrlxdatalayer.provider, name: str): @@ -141,24 +140,24 @@ def provide_fbs(provider: ctrlxdatalayer.provider, name: str): variantFlatbuffers = Variant() result = variantFlatbuffers.set_flatbuffers(builder.Output()) if result != ctrlxdatalayer.variant.Result.OK: - print("ERROR creating variant flatbuffers failed with:", result) + print("ERROR creating variant flatbuffers failed with:", result, flush=True) return # Create and register flatbuffers provider node - print("Creating flatbuffers provider node " + address_base + name) + print("Creating flatbuffers provider node " + address_base + name, flush=True) provider_node_fbs = MyProviderNode( provider, address_base + name, variantFlatbuffers) result = provider_node_fbs.register_node() if result != ctrlxdatalayer.variant.Result.OK: print("ERROR Registering node " + address_base + - name + " failed with:", result) + name + " failed with:", result, flush=True) return provider_node_fbs def provide_string(provider: ctrlxdatalayer.provider, name: str): # Create and register simple string provider node - print("Creating string provider node " + address_base + name) + print("Creating string provider node " + address_base + name, flush=True) variantString = Variant() variantString.set_string("myString") provider_node_str = MyProviderNode( @@ -166,7 +165,7 @@ def provide_string(provider: ctrlxdatalayer.provider, name: str): result = provider_node_str.register_node() if result != ctrlxdatalayer.variant.Result.OK: print("ERROR Registering node " + address_base + - name + " failed with:", result) + name + " failed with:", result, flush=True) return provider_node_str diff --git a/samples-python/datalayer.remote.debug/.vscode/tasks.json b/samples-python/datalayer.remote.debug/.vscode/tasks.json index 72aaf14d..6fe5bc49 100644 --- a/samples-python/datalayer.remote.debug/.vscode/tasks.json +++ b/samples-python/datalayer.remote.debug/.vscode/tasks.json @@ -1,36 +1,213 @@ { - // See https://go.microsoft.com/fwlink/?LinkId=733558 - // for the documentation about the tasks.json format - "version": "2.0.0", - "tasks": [ - { - "label": "0 Install venv and packages", - "type": "shell", - "command": "bash", - "args": ["install-venv.sh"], - "problemMatcher": [] - }, - { - "label": "build snap amd64", - "type": "shell", - "command": "bash", - "args": ["build-snap-amd64.sh"], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build snap arm64", - "type": "shell", - "command": "bash", - "args": ["build-snap-arm64.sh"], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - } - ] + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "Install venv", + "type": "shell", + "command": "bash", + "args": [ + "install-venv.sh" + ], + "problemMatcher": [] + }, + { + "label": "Build snap amd64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-amd64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build snap arm64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-arm64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + ], + "inputs": [ + { + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", + "type": "promptString", + "description": "IP address", + "default": "192.168.1.1" + }, + { + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", + "type": "promptString", + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" + }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" + } + ] } \ No newline at end of file diff --git a/samples-python/datalayer.remote.debug/debugging.py b/samples-python/datalayer.remote.debug/debugging.py index 3b157146..a8703b4e 100644 --- a/samples-python/datalayer.remote.debug/debugging.py +++ b/samples-python/datalayer.remote.debug/debugging.py @@ -31,7 +31,7 @@ def breakpoint(): """Set a breakpoint. - This function can be used to set a fix breakpoint into the programing code. + This function can be used to set a fix breakpoint into the programming code. The call is ineffective if debug is not activated (by providing a valid port number via command line parameter) """ if debugging_enabled: @@ -54,11 +54,11 @@ def wait_for_client(port: int): """ address = ('0.0.0.0', port) # Accept incomming calls from all network interfaces - print('Accepting remote debug client attaches to port', port) + print('Accepting remote debug client attaches to port', port, flush=True) debugpy.listen(address) debugpy.wait_for_client() - print('Debugger is attached!') + print('Debugger is attached!', flush=True) breakpoint() diff --git a/samples-python/datalayer.remote.debug/main.py b/samples-python/datalayer.remote.debug/main.py index 28f72826..40f226bd 100644 --- a/samples-python/datalayer.remote.debug/main.py +++ b/samples-python/datalayer.remote.debug/main.py @@ -43,14 +43,14 @@ def main(): print() print("========================================================================") - print("sdk-py-datalayer-client - A ctrlX Data Layer Client App in Python") + print("sdk-py-datalayer-client - A ctrlX Data Layer Client App in Python", flush=True) with ctrlxdatalayer.system.System("") as datalayer_system: datalayer_system.start(False) client, connection_string = get_client(datalayer_system) if client is None: - print("ERROR Connecting", connection_string, "failed.") + print("ERROR Connecting", connection_string, "failed.", flush=True) sys.exit(1) with client: @@ -73,18 +73,18 @@ def main(): sub_prop.set_flatbuffers(builder.Output()) # Create subscription - print("INFO Creating subscription") + print("INFO Creating subscription", flush=True) result, sub = client.create_subscription_sync( sub_prop, cb_subscription_sync) if result is not Result.OK: - print("ERROR Creating subscription failed:", result) + print("ERROR Creating subscription failed:", result, flush=True) # Add subscription node - print("INFO Add subscription node") + print("INFO Add subscription node", flush=True) sub_adr = "framework/metrics/system/cpu-utilisation-percent" result = sub.subscribe(sub_adr) if result is not Result.OK: - print("ERROR Adding subscription node failed:", result) + print("ERROR Adding subscription node failed:", result, flush=True) while client.is_connected(): @@ -93,22 +93,22 @@ def main(): addr = "framework/metrics/system/memused-percent" result, read_var = client.read_sync(addr) val = read_var.get_float64() - print("INFO read_sync: %s, %s: %f" % (dt_str, addr, val)) + print("INFO read_sync: %s, %s: %f" % (dt_str, addr, val), flush=True) time.sleep(5.0) - print("ERROR Data Layer connection") - print("INFO Close subscription") + print("ERROR Data Layer connection", flush=True) + print("INFO Close subscription", flush=True) sub.close() - print("INFO Stopping Data Layer system") + print("INFO Stopping Data Layer system", flush=True) datalayer_system.stop(True) # Response notify callback function def cb_subscription_sync(result: Result, items: List[ctrlxdatalayer.subscription.NotifyItem], userdata): if result is not Result.OK: - print("ERROR notify subscription:", result) + print("ERROR notify subscription:", result, flush=True) return timestamp = items[0].get_timestamp() # convert ldap to unix timestamp @@ -117,11 +117,11 @@ def cb_subscription_sync(result: Result, items: List[ctrlxdatalayer.subscription address = items[0].get_address() val = Variant.get_float64(items[0].get_data()) print("INFO Subscription notification: %s, %s: %f" % - (dt_str, address, val)) + (dt_str, address, val), flush=True) if __name__ == '__main__': print('Number of arguments:', len(sys.argv), 'arguments.') - print('Argument List:', str(sys.argv)) + print('Argument List:', str(sys.argv), flush=True) debugging.init() main() diff --git a/samples-python/logbook/.vscode/tasks.json b/samples-python/logbook/.vscode/tasks.json index 72aaf14d..6fe5bc49 100644 --- a/samples-python/logbook/.vscode/tasks.json +++ b/samples-python/logbook/.vscode/tasks.json @@ -1,36 +1,213 @@ { - // See https://go.microsoft.com/fwlink/?LinkId=733558 - // for the documentation about the tasks.json format - "version": "2.0.0", - "tasks": [ - { - "label": "0 Install venv and packages", - "type": "shell", - "command": "bash", - "args": ["install-venv.sh"], - "problemMatcher": [] - }, - { - "label": "build snap amd64", - "type": "shell", - "command": "bash", - "args": ["build-snap-amd64.sh"], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build snap arm64", - "type": "shell", - "command": "bash", - "args": ["build-snap-arm64.sh"], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - } - ] + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "Install venv", + "type": "shell", + "command": "bash", + "args": [ + "install-venv.sh" + ], + "problemMatcher": [] + }, + { + "label": "Build snap amd64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-amd64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build snap arm64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-arm64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + ], + "inputs": [ + { + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", + "type": "promptString", + "description": "IP address", + "default": "192.168.1.1" + }, + { + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", + "type": "promptString", + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" + }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" + } + ] } \ No newline at end of file diff --git a/samples-python/logbook/logbook/app.py b/samples-python/logbook/logbook/app.py index 044e6505..29e2d0e2 100644 --- a/samples-python/logbook/logbook/app.py +++ b/samples-python/logbook/logbook/app.py @@ -1,6 +1,6 @@ # MIT License # -# Copyright (c) 2021 Bosch Rexroth AG +# Copyright (c) 2021-2022 Bosch Rexroth AG # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -24,7 +24,7 @@ from systemd.journal import JournaldLogHandler def run(): - print("Simple Snap for insert different loglevels with Python") + print("Simple snap in Python using logging with different log levels", flush=True) log = logging.getLogger() log.setLevel(logging.DEBUG) diff --git a/samples-python/logbook/setup.py b/samples-python/logbook/setup.py index 13d60f30..99667bdd 100644 --- a/samples-python/logbook/setup.py +++ b/samples-python/logbook/setup.py @@ -2,7 +2,7 @@ setup(name = 'sdk-py-logbook', - version='2.0.0', + version='2.3.0', description = 'Logbook sample written in Python for ctrlX', author = 'SDK Team', packages = ['logbook'], diff --git a/samples-python/logbook/snap/snapcraft.yaml b/samples-python/logbook/snap/snapcraft.yaml index 8fd51948..a93d32e7 100644 --- a/samples-python/logbook/snap/snapcraft.yaml +++ b/samples-python/logbook/snap/snapcraft.yaml @@ -1,5 +1,5 @@ name: sdk-py-logbook -version: 2.0.0 +version: 2.3.0 summary: Logbook sample written in Python for ctrlX title: sdk-py-logbook description: | diff --git a/samples-python/webserver/.vscode/tasks.json b/samples-python/webserver/.vscode/tasks.json index 897c1e8a..6fe5bc49 100644 --- a/samples-python/webserver/.vscode/tasks.json +++ b/samples-python/webserver/.vscode/tasks.json @@ -1,58 +1,213 @@ { - // See https://go.microsoft.com/fwlink/?LinkId=733558 - // for the documentation about the tasks.json format - "version": "2.0.0", - "tasks": [ - { - "label": "0 Install venv and packages", - "type": "shell", - "command": "bash", - "args": ["install-venv.sh"], - "problemMatcher": [] - }, - { - "label": "build snap amd64", - "type": "shell", - "command": "bash", - "args": ["build-snap-amd64.sh"], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build snap arm64", - "type": "shell", - "command": "bash", - "args": ["build-snap-arm64.sh"], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build and install snap amd64", - "type": "shell", - "command": "bash", - "args": ["build-install-snap-amd64.sh"], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - }, - { - "label": "build and install snap arm64", - "type": "shell", - "command": "bash", - "args": ["build-install-snap-arm64.sh"], - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - } - ] + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "Install venv", + "type": "shell", + "command": "bash", + "args": [ + "install-venv.sh" + ], + "problemMatcher": [] + }, + { + "label": "Build snap amd64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-amd64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build snap arm64", + "type": "shell", + "command": "bash", + "args": [ + "build-snap-arm64.sh" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Network Adapter", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-NA" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE virtual Port Forwarding", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-ctrlx-virt-PF" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE 192.168.1.1", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-addr", + "192.168.1.1" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "Build upload snap - ctrlX CORE", + "type": "shell", + "command": "../../scripts/build-upload-log-snap.sh", + "args": [ + "-build", + "${input:Build}", + "-upload", + "${input:Upload}", + "-logs", + "${input:Logs}", + "-svc", + "${input:Service}", + "-addr", + "${input:IPAddress}", + "-ssl-port", + "${input:SSLPort}", + "-ssl-usr", + "${input:SSLUser}", + "-ssl-pwd", + "${input:SSLPwd}", + "-arch", + "${input:Arch}", + "-ssh-port", + "${input:SSHPort}", + "-ssh-usr", + "${input:SSHUser}", + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + ], + "inputs": [ + { + "id": "Build", + "type": "pickString", + "description": "Build snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "Upload", + "type": "pickString", + "description": "Upload snap?", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "IPAddress", + "type": "promptString", + "description": "IP address", + "default": "192.168.1.1" + }, + { + "id": "SSLPort", + "type": "pickString", + "description": "HTTPS (SSL) port number", + "options": [ + "443", + "8443" + ], + "default": "443" + }, + { + "id": "Service", + "type": "pickString", + "description": "Switch to state SERVICE before installing the snap: y/n", + "options": [ + "y", + "n" + ], + "default": "n" + }, + { + "id": "SSLUser", + "type": "promptString", + "description": "HTTPS (SSL) user name", + "default": "boschrexroth" + }, + { + "id": "SSLPwd", + "type": "promptString", + "password": true, + "description": "HTTPS (SSL) password", + "default": "boschrexroth" + }, + { + "id": "Arch", + "type": "pickString", + "description": "CPU architecture?", + "options": [ + "arm64", + "amd64" + ], + "default": "arm64" + }, + { + "id": "Logs", + "type": "pickString", + "description": "Show logs - SSH must be enabled on ctrlX: y/n", + "options": [ + "y", + "n" + ], + "default": "y" + }, + { + "id": "SSHPort", + "type": "pickString", + "description": "SSH port number", + "options": [ + "22", + "8022" + ], + "default": "22" + }, + { + "id": "SSHUser", + "type": "promptString", + "description": "SSH user name", + "default": "rexroot" + } + ] } \ No newline at end of file diff --git a/samples-python/webserver/README.md b/samples-python/webserver/README.md index 9fce1a73..0e6da08e 100644 --- a/samples-python/webserver/README.md +++ b/samples-python/webserver/README.md @@ -27,14 +27,22 @@ The integration of the app inside ctrlX Core webpage (sidebar and overview integ The app has these modules: -* __main.py__ starts the web server. In snap environment an Unix socket connection is established otherwise a TCP/IP connection. -* __unix_socket_http_server.py *)__ HTTP web server class (wrapper) to use unix sockets instead of TCP/IP -* __web/web_server.py *)__ HTTP request handler class for both UNIX sockets and TCP/IP -* __web/web_token.py__ contains a helper function to check permissions using jwt -* __app/datalayer_client.py__ handles the Data Layer node data access. -* __app/datalayer_helper.py__ handles the Data Layer client connection. - -*) +* __main.py__ connects to the ctrlX Data Layer and starts the web server. In snap environment an Unix socket connection is established otherwise a TCP/IP connection. + +* __app/__ +* __datalayer.py__ handles the Data Layer node data access. +* __ctrlx_datalayer_helper.py__ handles the Data Layer client connection. + +* __web/__ +* __unix_socket_server.py *)__ Web server class (wrapper) to use unix sockets instead of TCP/IP +* __request_handler.py *)__ Request handler class for both UNIX sockets and TCP/IP +* __web_token.py__ contains a helper function to check permissions using jwt +* __www/__ +* __favicon.png__ Favicon for the web site. +* __index.html__ The web site. +* __invalid-token.html__ The web content which is send when the token was wrong. +* __stylesheet.css__ Defines the style of the web site. + ___ ## License diff --git a/samples-python/webserver/app/datalayer_helper.py b/samples-python/webserver/app/ctrlx_datalayer_helper.py similarity index 100% rename from samples-python/webserver/app/datalayer_helper.py rename to samples-python/webserver/app/ctrlx_datalayer_helper.py diff --git a/samples-python/webserver/app/datalayer.py b/samples-python/webserver/app/datalayer.py new file mode 100644 index 00000000..a3eff2bc --- /dev/null +++ b/samples-python/webserver/app/datalayer.py @@ -0,0 +1,283 @@ +# MIT License +# +# Copyright (c) 2020-2022 Bosch Rexroth AG +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + + +from comm.datalayer import Metadata + +import ctrlxdatalayer +from ctrlxdatalayer.variant import Result, Variant, VariantType + +from app.ctrlx_datalayer_helper import get_client + +class DataLayer: + + def __init__(self, ip="192.168.1.1", + user="boschrexroth", + password="boschrexroth", + ssl_port=443) -> None: + + self.system = ctrlxdatalayer.system.System("") + self.client = None + + def __enter__(self): + """ + use the python context manager + """ + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + """ + use the python context manager + """ + self.system = None + self.client = None + + def start(self): + self.system.start(False) + + def stop(self): + self.system.stop(False) + + def connect_client(self, ip="192.168.1.1", + user="boschrexroth", + password="boschrexroth", + https_port=443): + + self.client, connection_string = get_client( + self.system, ip, user, password, https_port) + + return self.client, connection_string + + def read_node(self, address: str): + + result, value = self.get_value(address) + return result.name, value + + def write_node(self, address: str, value: str): + + result = self.set_value(address, value) + return result.name + + def get_value(self, address): + + print("Reading", address, flush=True) + + result, data = self.client.read_sync(address) + if result != Result.OK: + print("ERROR Reading Data Layer failed with:", result, flush=True) + return result, data + + with data: + + variant_type = data.get_type() + + if variant_type == VariantType.ARRAY_BOOL8: + return Result.OK, data.get_array_bool8() + + if variant_type == VariantType.ARRAY_FLOAT32: + return Result.OK, data.get_array_float32() + + if variant_type == VariantType.ARRAY_FLOAT64: + return Result.OK, data.get_array_float64() + + if variant_type == VariantType.ARRAY_INT16: + return Result.OK, data.get_array_int16() + + if variant_type == VariantType.ARRAY_INT32: + return Result.OK, data.get_array_int32() + + if variant_type == VariantType.ARRAY_INT64: + return Result.OK, data.get_array_int64() + + if variant_type == VariantType.ARRAY_INT8: + return Result.OK, data.get_array_int8() + + if variant_type == VariantType.ARRAY_STRING: + return Result.OK, data.get_array_string() + + if variant_type == VariantType.ARRAY_UINT16: + return Result.OK, data.get_array_uint16() + + if variant_type == VariantType.ARRAY_UINT32: + return Result.OK, data.get_array_uint32() + + if variant_type == VariantType.ARRAY_UINT64: + return Result.OK, data.get_array_uint64() + + if variant_type == VariantType.ARRAY_UINT8: + return Result.OK, data.get_array_uint8() + + if variant_type == VariantType.BOOL8: + return Result.OK, data.get_bool8() + + if variant_type == VariantType.FLATBUFFERS: + return self.getFlatbuffersAsJsonStr(address, data) + + if variant_type == VariantType.FLOAT32: + return Result.OK, data.get_float32() + + if variant_type == VariantType.FLOAT64: + return Result.OK, data.get_float64() + + if variant_type == VariantType.INT16: + return Result.OK, data.get_int16() + + if variant_type == VariantType.INT32: + return Result.OK, data.get_int32() + + if variant_type == VariantType.INT64: + return Result.OK, data.get_int64() + + if variant_type == VariantType.INT8: + return Result.OK, data.get_int8() + + if variant_type == VariantType.STRING: + return Result.OK, data.get_string() + + if variant_type == VariantType.UINT16: + return Result.Ok, data.get_uint16() + + if variant_type == VariantType.UINT32: + return Result.Ok, data.get_uint32() + + if variant_type == VariantType.UINT64: + return Result.OK, data.get_uint64() + + if variant_type == VariantType.UINT8: + return Result.OK, data.get_uint8() + + print( + f"WARNING Supported Variant Type: {variant_type}", flush=True) + return Result.UNSUPPORTED, None + + def getFlatbuffersAsJsonStr(self, addr: str, fbs_value: Variant): + + result, fbs_metadata = self.client.metadata_sync(addr) + if result != Result.OK: + return result, "" + + metadata_root = Metadata.Metadata.GetRootAsMetadata( + fbs_metadata.get_flatbuffers()) + if metadata_root == None: + return result, "" + + address_read_type = "" + for i in range(0, metadata_root.ReferencesLength()): + reference = metadata_root.References(i) + + if reference is None: + continue + + if reference.Type().decode('utf-8').lower() == "readtype": + address_read_type = reference.TargetAddress().decode('utf-8') + break + + if address_read_type == "": + return Result.INVALID_VALUE, "" + + result, fbs_type = self.client.read_sync(address_read_type) + if result != Result.OK: + return result, "" + + result, jsonVariant = self.system.json_converter( + ).converter_generate_json_complex(fbs_value, fbs_type, 2) + if result != Result.OK: + return result, "" + + return Result.OK, jsonVariant.get_string() + + def set_value(self, address, value): + + print("Checking VarianType of", address, flush=True) + + # Read first to check VariantType + result, variant = self.client.read_sync(address) + if result != Result.OK: + return result + + with variant: + + variant_type = variant.get_type() + + if variant_type == VariantType.BOOL8: + variant.set_bool8(bool(value)) + result, _ = self.client.write_sync(address, variant) + return result + + if variant_type == VariantType.FLOAT32: + variant.set_float32(float(value)) + result, _ = self.client.write_sync(address, variant) + return result + + if variant_type == VariantType.FLOAT64: + variant.set_float64(float(value)) + result, _ = self.client.write_sync(address, variant) + return result + + if variant_type == VariantType.INT16: + variant.set_int16(int(value)) + result, _ = self.client.write_sync(address, variant) + return result + + if variant_type == VariantType.INT32: + variant.set_int32(int(value)) + result, _ = self.client.write_sync(address, variant) + return result + + if variant_type == VariantType.INT64: + variant.set_int64(int(value)) + result, _ = self.client.write_sync(address, variant) + return result + + if variant_type == VariantType.INT8: + variant.set_int8(int(value)) + result, _ = self.client.write_sync(address, variant) + return result + + if variant_type == VariantType.STRING: + variant.set_string(value) + result, _ = self.client.write_sync(address, variant) + return result + + if variant_type == VariantType.UINT16: + variant.set_uint16(int(value)) + result, _ = self.client.write_sync(address, variant) + return result + + if variant_type == VariantType.UINT32: + variant.set_uint32(int(value)) + result, _ = self.client.write_sync(address, variant) + return result + + if variant_type == VariantType.UINT64: + variant.set_uint64(int(value)) + result, _ = self.client.write_sync(address, variant) + return result + + if variant_type == VariantType.UINT8: + variant.set_uint8(int(value)) + result, _ = self.client.write_sync(address, variant) + return result + + print("ERROR Unsupported Variant Type:", variant_type, flush=True) + return Result.UNSUPPORTED + diff --git a/samples-python/webserver/app/datalayer_client.py b/samples-python/webserver/app/datalayer_client.py deleted file mode 100644 index 3cdc2e41..00000000 --- a/samples-python/webserver/app/datalayer_client.py +++ /dev/null @@ -1,306 +0,0 @@ -# MIT License -# -# Copyright (c) 2020-2022 Bosch Rexroth AG -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -import logging - -from comm.datalayer import Metadata - -import ctrlxdatalayer -from ctrlxdatalayer.variant import (Result, VariantType) - -import app.datalayer_helper - -log = logging.getLogger() - -global global_datalayer_system -global global_datalayer_client - - -def data_layer_start(): - - global global_datalayer_system - - global_datalayer_system = ctrlxdatalayer.system.System("") - global_datalayer_system.start(False) - return global_datalayer_system - -def data_layer_stop(): - - global global_datalayer_system - - global_datalayer_system.stop(False) - - -def data_layer_client_connect(ip="192.168.1.1", - user="boschrexroth", - password="boschrexroth", - https_port=443): - - global global_datalayer_system - global global_datalayer_client - - global_datalayer_client, connection_string = app.datalayer_helper.get_client( - global_datalayer_system, ip, user, password, https_port) - - if global_datalayer_client is None: - return None, "Connecting " + connection_string + " failed!" - - return global_datalayer_client, "" - - -def read_node(address: str): - - result, value = get_value(address) - return result.name, value - - -def write_node(address: str, value: str): - - result = set_value(address, value) - return result.name - - -def get_value(address): - - global global_datalayer_system - global global_datalayer_client - - log.debug("Reading " + address) - - result, data = global_datalayer_client.read_sync(address) - if result != Result.OK: - log.error("ERROR Reading Data Layer failed with: %i", result) - return result, data - - with data: - - vt = data.get_type() - - if vt == VariantType.ARRAY_BOOL8: - return Result.OK, data.get_array_bool8() - - if vt == VariantType.ARRAY_FLOAT32: - return Result.OK, data.get_array_float32() - - if vt == VariantType.ARRAY_FLOAT64: - return Result.OK, data.get_array_float64() - - if vt == VariantType.ARRAY_INT16: - return Result.OK, data.get_array_int16() - - if vt == VariantType.ARRAY_INT32: - return Result.OK, data.get_array_int32() - - if vt == VariantType.ARRAY_INT64: - return Result.OK, data.get_array_int64() - - if vt == VariantType.ARRAY_INT8: - return Result.OK, data.get_array_int8() - - if vt == VariantType.ARRAY_STRING: - return Result.OK, data.get_array_string() - - if vt == VariantType.ARRAY_UINT16: - return Result.OK, data.get_array_uint16() - - if vt == VariantType.ARRAY_UINT32: - return Result.OK, data.get_array_uint32() - - if vt == VariantType.ARRAY_UINT64: - return Result.OK, data.get_array_uint64() - - if vt == VariantType.ARRAY_UINT8: - return Result.OK, data.get_array_uint8() - - if vt == VariantType.BOOL8: - return Result.OK, data.get_bool8() - - if vt == VariantType.FLATBUFFERS: - - # Get type address for flatbuffers information - type_address = get_type_address(address) - if type_address is None: - log.error("ERROR Type Address is none") - return Result.INVALID_CONFIGURATION, None - - # Read type address as variant - result, bfbs = global_datalayer_client.read_sync(type_address) - if result != Result.OK: - log.error("ERROR Reading Type Value failed with: ", result) - return Result.INVALID_CONFIGURATION, None - - # Convert variant flatbuffers data to json type - converter = global_datalayer_system.json_converter() - result, json = converter.converter_generate_json_complex( - data, bfbs, -1) - if result != Result.OK: - log.error("ERROR Converting json failed with: ", result) - return Result.INVALID_CONFIGURATION, None - - return Result.OK, json.get_string() - - if vt == VariantType.FLOAT32: - return Result.OK, data.get_float32() - - if vt == VariantType.FLOAT64: - return Result.OK, data.get_float64() - - if vt == VariantType.INT16: - return Result.OK, data.get_int16() - - if vt == VariantType.INT32: - return Result.OK, data.get_int32() - - if vt == VariantType.INT64: - return Result.OK, data.get_int64() - - if vt == VariantType.INT8: - return Result.OK, data.get_int8() - - if vt == VariantType.STRING: - return Result.OK, data.get_string() - - if vt == VariantType.UINT16: - return Result.Ok, data.get_uint16() - - if vt == VariantType.UINT32: - return Result.Ok, data.get_uint32() - - if vt == VariantType.UINT64: - return Result.OK, data.get_uint64() - - if vt == VariantType.UINT8: - return Result.OK, data.get_uint8() - - log.warning("WARNING Supported Variant Type:", vt) - return Result.UNSUPPORTED, None - - -def get_type_address(address: str): - - global global_datalayer_client - - log.debug("Reading metadata " + address) - - result, metadata = global_datalayer_client.metadata_sync(address) - if result != Result.OK: - log.error("ERROR Reading metadata of ", - address, " failed with: ", result) - return - - metadata_root = Metadata.Metadata.GetRootAsMetadata( - metadata.get_flatbuffers()) - - if metadata_root.ReferencesLength() == 0: - log.error("ERROR Metadata references are empty") - return - - for i in range(0, metadata_root.ReferencesLength()): - reference = metadata_root.References(i) - - if reference is None: - continue - - if reference.Type().decode('utf-8').lower() == "readtype": - type_address = reference.TargetAddress().decode('utf-8') - return type_address - - return None - - -def set_value(address, value): - - global global_datalayer_client - - log.debug("Checking VarianType of " + address) - - # Read first to check VariantType - result, variant = global_datalayer_client.read_sync(address) - if result != Result.OK: - return result - - with variant: - - vt = variant.get_type() - - if vt == VariantType.BOOL8: - variant.set_bool8(bool(value)) - result, _ = global_datalayer_client.write_sync(address, variant) - return result - - if vt == VariantType.FLOAT32: - variant.set_float32(float(value)) - result, _ = global_datalayer_client.write_sync(address, variant) - return result - - if vt == VariantType.FLOAT64: - variant.set_float64(float(value)) - result, _ = global_datalayer_client.write_sync(address, variant) - return result - - if vt == VariantType.INT16: - variant.set_int16(int(value)) - result, _ = global_datalayer_client.write_sync(address, variant) - return result - - if vt == VariantType.INT32: - variant.set_int32(int(value)) - result, _ = global_datalayer_client.write_sync(address, variant) - return result - - if vt == VariantType.INT64: - variant.set_int64(int(value)) - result, _ = global_datalayer_client.write_sync(address, variant) - return result - - if vt == VariantType.INT8: - variant.set_int8(int(value)) - result, _ = global_datalayer_client.write_sync(address, variant) - return result - - if vt == VariantType.STRING: - variant.set_string(value) - result, _ = global_datalayer_client.write_sync(address, variant) - return result - - if vt == VariantType.UINT16: - variant.set_uint16(int(value)) - result, _ = global_datalayer_client.write_sync(address, variant) - return result - - if vt == VariantType.UINT32: - variant.set_uint32(int(value)) - result, _ = global_datalayer_client.write_sync(address, variant) - return result - - if vt == VariantType.UINT64: - variant.set_uint64(int(value)) - result, _ = global_datalayer_client.write_sync(address, variant) - return result - - if vt == VariantType.UINT8: - variant.set_uint8(int(value)) - result, _ = global_datalayer_client.write_sync(address, variant) - return result - - log.error("ERROR Unsupported Variant Type:", vt) - return Result.UNSUPPORTED diff --git a/samples-python/webserver/main.py b/samples-python/webserver/main.py index 5874cb3e..5e0fee5e 100644 --- a/samples-python/webserver/main.py +++ b/samples-python/webserver/main.py @@ -23,85 +23,58 @@ # SOFTWARE. import os -import time import sys -import logging import threading -from systemd.journal import JournaldLogHandler - import http.server -import web.web_server -import web.unix_socket_http_server - -from comm.datalayer import Metadata +import web.request_handler +import web.unix_socket_server -import app.datalayer_client +import app.datalayer -log = logging.getLogger() httpServerPort = 12345 token = 'eyJhbGciOiJFUzM4NCIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NjAxNDg3NzQsImlhdCI6MTY2MDExOTk3NCwiaWQiOiIxMDAwIiwibmFtZSI6ImJvc2NocmV4cm90aCIsIm5vbmNlIjoiMGU0NTVhODMtMThlOC00YjY2LTllMWUtYTE0NWM2ZWIzZWQzIiwicGxjaGFuZGxlIjowLCJyZW1vdGVhdXRoIjoiIiwic2NvcGUiOlsicmV4cm90aC1kZXZpY2UuYWxsLnJ3eCJdfQ.VqCCRh2ga1Ujn5C_vBAf7dZHXNr6gY0Aqvrwu39_6L9d7fWBYXr-MmqdYxGB85fHBhs56MFrCacYjN5SbctqSyH1LTeXLKAdP4Etx8V7B2QB_5XZdVCLqIwYOAU8Gdzv' def main(): - log.setLevel(logging.DEBUG) - - snap_environment = 'SNAP' in os.environ - if snap_environment is False: - # Snap environment: Avoid logging message twice - log.addHandler(logging.StreamHandler(sys.stdout)) - log.addHandler(JournaldLogHandler()) - - datalayer_system = app.datalayer_client.data_layer_start() + web.request_handler.data_layer = app.datalayer.DataLayer() + web.request_handler.data_layer.start() - # ctrlX CORE virtual with port forwarding: - datalayer_client, error_msg = app.datalayer_client.data_layer_client_connect(ip="10.0.2.2", https_port=8443) + client, connection_string = web.request_handler.data_layer.connect_client(ip="10.0.2.2", https_port=8443) + if client == None: + print("ERROR Could not connect", connection_string, flush=True) + return - # ctrlX CORE virtual with network adapter: - #app.datalayer_client.datalayer_client, error_msg = data_layer_client_connect() - - if error_msg: - log.error(error_msg) - sys.exit(1) - - new_thread = threading.Thread( - target=thread_start, args=(snap_environment, )) + new_thread = threading.Thread(target=thread_start) new_thread.start() - while datalayer_client.is_connected(): - time.sleep(5) - - log.debug('') - log.debug('Data Layer connection broken - stopping web server...') + new_thread.join() - app.datalayer_client.data_layer_stop() + web.request_handler.data_layer.stop() - sys.exit(1) + sys.exit(0) -def thread_start(snap_environment: bool): +def thread_start(): # If running with a snap (on a ctrlX) start UNIX socket # If running as app in an app builder envorinemtn start a TCP server - run_webserver_unixsock() if snap_environment else run_webserver_tcp() + run_webserver_unixsock() if 'SNAP' in os.environ else run_webserver_tcp() def run_webserver_tcp(): - with http.server.HTTPServer(('', httpServerPort), web.web_server.WebServer) as http_server: + with http.server.HTTPServer(('', httpServerPort), web.request_handler.RequestHandler) as http_server: - log.debug("") - log.debug('TCP/IP server started - listening on 0.0.0.0:%i', - httpServerPort) - log.debug("") - log.debug( + print('TCP/IP server started - listening on 0.0.0.0:', httpServerPort) + print("") + print( '------------------Copy this link into the address field of your browser ----------------------') - log.debug('http://localhost:'+str(httpServerPort) + - '/python-webserver?token='+token) - log.debug( - '----------------------------------------------------------------------------------------------') - log.debug("") + print('http://localhost:'+str(httpServerPort) + + '/python-webserver?token='+token) + print( + '----------------------------------------------------------------------------------------------', flush=True) http_server.serve_forever() @@ -121,9 +94,9 @@ def run_webserver_unixsock(): except OSError: pass - with web.unix_socket_http_server.UnixSocketHttpServer(sock_file, web.web_server.WebServer) as http_server: + with web.unix_socket_server.UnixSocketServer(sock_file, web.request_handler.RequestHandler) as http_server: - log.debug('UNIX SOCKET server started - listening on %s', sock_file) + print('UNIX SOCKET server started - listening on', sock_file, flush=True) http_server.serve_forever() diff --git a/samples-python/webserver/setup.py b/samples-python/webserver/setup.py index 4fd37faf..2d84a67a 100644 --- a/samples-python/webserver/setup.py +++ b/samples-python/webserver/setup.py @@ -1,11 +1,11 @@ from setuptools import setup setup(name='sdk-py-webserver', - version='2.0.0', + version='2.3.0', description='Webserver Sample written in Python for ctrlX', author='SDK Team', install_requires=['systemd','PyJWT', 'ctrlx-datalayer', 'ctrlx-fbs'], scripts=['main.py'], packages=['app', 'web'], - license='Copyright (c) 2020-2021 Bosch Rexroth AG, Licensed under MIT License' + license='Copyright (c) 2020-2022 Bosch Rexroth AG, Licensed under MIT License' ) diff --git a/samples-python/webserver/web/web_server.py b/samples-python/webserver/web/request_handler.py similarity index 78% rename from samples-python/webserver/web/web_server.py rename to samples-python/webserver/web/request_handler.py index 65cc1d8c..5ad0fc1f 100644 --- a/samples-python/webserver/web/web_server.py +++ b/samples-python/webserver/web/request_handler.py @@ -23,23 +23,22 @@ import os import traceback -import http.server +import http.server import web.web_token from urllib.parse import unquote, parse_qs, urlparse from json import dumps, loads -import app.datalayer_client +import app.datalayer -import logging -log = logging.getLogger() +data_layer : app.datalayer.DataLayer - -class WebServer(http.server.BaseHTTPRequestHandler): +class RequestHandler(http.server.BaseHTTPRequestHandler): # Form parameters saved server side - readPath = "framework/metrics/system/cpu-utilisation-percent" # "datalayer/subscriptions/settings" + # "datalayer/subscriptions/settings" + readPath = "datalayer/subscriptions/settings" # "framework/metrics/system/cpu-utilisation-percent" readValue = "" readResult = "" writePath = "sdk-py-provider-alldata/dynamic/int64" @@ -55,7 +54,7 @@ def get_www_file_path(self, relative_path): if len(relative_path) <= 0: relative_path = self.path - log.debug("get_www_file_path relative_path: %s", relative_path) + print("get_www_file_path relative_path: %s", relative_path) rel_www_path = "/www/" + os.path.basename(relative_path) @@ -63,7 +62,7 @@ def get_www_file_path(self, relative_path): result_path = os.getcwd() + rel_www_path if snap_path is None else snap_path + rel_www_path - log.debug("get_www_file_path result_path: %s", result_path) + print("get_www_file_path result_path:", result_path, flush=True) return result_path @@ -81,8 +80,8 @@ def send_file_response(self, content_type, rel_path=""): self.send_response_and_header(200, content_type) self.wfile.write(bufferedReader.read()) except Exception: - log.error("Exception opening and sending file: %s", path) - log.exception(traceback.format_exc()) + print("EXCEPTION Opening and sending file:", path) + print(traceback.format_exc(), flush=True) self.send_response_and_header(404, content_type) def send_html_file_response(self, rel_path=""): @@ -95,13 +94,13 @@ def send_html_file_response(self, rel_path=""): self.send_response_and_header(200, content_type) self.wfile.write(bytes(bufferedReader.read(), 'utf-8')) except Exception: - log.error("Exception opening and sending file: %s", path) - log.exception(traceback.format_exc()) + print("EXCEPTION opening and sending file:", path) + print(traceback.format_exc(), flush=True) self.send_response_and_header(404, content_type) def do_GET(self): # GET Requests from client - log.debug("GET %s", self.path) + print("GET", self.path, flush=True) # Attempt To Send Different Files if self.path.endswith(".png"): @@ -164,16 +163,19 @@ def do_GET(self): '$(permissions_write_text)', '' if permissions_write else "'disabled'") # Text must be surrounded by ' ' # Set read content - htmlX = htmlX.replace('$(Server.readPath)', str(WebServer.readPath)) - htmlX = htmlX.replace('$(Server.readValue)', str(WebServer.readValue)) + htmlX = htmlX.replace('$(Server.readPath)', + str(RequestHandler.readPath)) + htmlX = htmlX.replace('$(Server.readValue)', + str(RequestHandler.readValue)) htmlX = htmlX.replace('$(Server.readResult)', - str(WebServer.readResult)) + str(RequestHandler.readResult)) - htmlX = htmlX.replace('$(Server.writePath)', str(WebServer.writePath)) + htmlX = htmlX.replace('$(Server.writePath)', + str(RequestHandler.writePath)) htmlX = htmlX.replace('$(Server.writeValue)', - str(WebServer.writeValue)) + str(RequestHandler.writeValue)) htmlX = htmlX.replace('$(Server.writeResult)', - str(WebServer.writeResult)) + str(RequestHandler.writeResult)) # Show permissions: 'True' or 'False' htmlX = htmlX.replace('$(permissions_rwx)', str( @@ -197,35 +199,35 @@ def do_POST(self): json = dumps(parse_qs(post_data)) data = loads(json) - log.debug("POST %s", str(data)) + print("POST", str(data), flush=True) # Evaluate post data if data['submit'][0] == 'Read Value': if 'node' in data: - WebServer.readPath = data['node'][0] + RequestHandler.readPath = data['node'][0] # Data Layer access - WebServer.readResult, WebServer.readValue = app.datalayer_client.read_node( - WebServer.readPath) + RequestHandler.readResult, RequestHandler.readValue = data_layer.read_node( + RequestHandler.readPath) else: - WebServer.readValue = '' - WebServer.readResult = 'INVALID NODE' + RequestHandler.readValue = '' + RequestHandler.readResult = 'INVALID NODE' if data['submit'][0] == 'Write Value': if 'node' in data and 'value' in data: - WebServer.writePath = data['node'][0] - WebServer.writeValue = data['value'][0] + RequestHandler.writePath = data['node'][0] + RequestHandler.writeValue = data['value'][0] # Data Layer access - WebServer.writeResult = app.datalayer_client.write_node( - WebServer.writePath, WebServer.writeValue) + RequestHandler.writeResult = data_layer.write_node( + RequestHandler.writePath, RequestHandler.writeValue) else: - WebServer.writeValue = '' - WebServer.writeResult = 'INVALID NODE' + RequestHandler.writeValue = '' + RequestHandler.writeResult = 'INVALID NODE' self.send_response(303) self.send_header('Content-type', 'text/html') diff --git a/samples-python/webserver/web/unix_socket_http_server.py b/samples-python/webserver/web/unix_socket_server.py similarity index 96% rename from samples-python/webserver/web/unix_socket_http_server.py rename to samples-python/webserver/web/unix_socket_server.py index a8c188ee..a6017796 100644 --- a/samples-python/webserver/web/unix_socket_http_server.py +++ b/samples-python/webserver/web/unix_socket_server.py @@ -27,7 +27,7 @@ from socketserver import UnixStreamServer -class UnixSocketHttpServer(UnixStreamServer): +class UnixSocketServer(UnixStreamServer): def get_request(self): request, _ = super().get_request() diff --git a/samples-sh/tpm2.consumer/.vscode/tasks.json b/samples-sh/tpm2.consumer/.vscode/tasks.json index 090b7fd4..c206002c 100644 --- a/samples-sh/tpm2.consumer/.vscode/tasks.json +++ b/samples-sh/tpm2.consumer/.vscode/tasks.json @@ -12,12 +12,11 @@ "type": "shell", "command": "snapcraft --target-arch='${input:arch}';snapcraft clean" } - ], "inputs": [ { "id": "arch", - "type":"pickString", + "type": "pickString", "description": "Architecture", "options": [ "amd64", diff --git a/scripts/build-upload-log-snap.sh b/scripts/build-upload-log-snap.sh new file mode 100644 index 00000000..b77b3030 --- /dev/null +++ b/scripts/build-upload-log-snap.sh @@ -0,0 +1,337 @@ +#!/bin/bash + +SECONDS_TO_WAIT_AFTER_SHOW_ARGUMENTS=2 +SECONDS_TO_WAIT_AFTER_UPLOAD=30 + +BUILD=y + +UPLOAD=y +ADDR=192.168.1.1 + +SSL_PORT=443 +SSL_USR=boschrexroth +SSL_PWD=boschrexroth + +SVC=n + +ARCH=arm64 + +LOGS=y +SSH_PORT=22 +SSH_USR=rexroot + +# Scanning parameter list + +i=0 +for arg in "$@"; do + i=$((i+1)) + argNext=$((i+1)) + + if grep -q "NA" <<<${arg} + then + ARCH=amd64 + fi + + if grep -q "PF" <<<${arg} + then + ADDR=10.0.2.2 + SSL_PORT=8443 + ARCH=amd64 + SSH_PORT=8022 + fi + + if grep -q "build" <<<${arg} + then + BUILD=${!argNext} + fi + + if grep -q "upload" <<<${arg} + then + UPLOAD=${!argNext} + fi + + if grep -q "ip" <<<${arg} + then + ADDR=${!argNext} + fi + + if grep -q "addr" <<<${arg} + then + ADDR=${!argNext} + fi + + if grep -q "ssl-port" <<<${arg} + then + SSL_PORT=${!argNext} + fi + + if grep -q "ssl-usr" <<<${arg} + then + SSL_USR=${!argNext} + fi + + if grep -q "ssl-pwd" <<<${arg} + then + SSL_PWD=${!argNext} + fi + + if grep -q "svc" <<<${arg} + then + SVC=${!argNext} + fi + + if grep -q "arch" <<<${arg} + then + ARCH=${!argNext} + fi + + if grep -q "logs" <<<${arg} + then + LOGS=${!argNext} + fi + + if grep -q "ssh-port" <<<${arg} + then + SSH_PORT=${!argNext} + fi + + if grep -q "ssh-usr" <<<${arg} + then + SSH_USR=${!argNext} + fi + + if grep -q "ssh-pwd" <<<${arg} + then + SSH_PWD=${!argNext} + fi + + if grep -q "help" <<<${arg} + then + echo " " + echo "-----------------------------------------------------" + echo "Build, upload and show snap logs" + echo " " + echo "Usage:" + echo "build-upload-log-snap.sh - Use default values for ctrlX CORE M3/4" + echo "" + echo "All command line parameters with their default value:" + echo "-----------------------------------------------------" + echo "-build Build snap" + echo " y Default: Include snap build" + echo " n Skip snap build" + echo " " + echo "-upload Upload snap" + echo " y Default: Servive State, Upload, Operation State" + echo " n Skip upload" + echo " " + echo "-logs Show snap logs" + echo " y Start remote: sudo snap logs -f ... " + echo " n No logs" + echo " " + echo "-addr IP address or name of the destination ctrlX CORE" + echo " 192.168.1.1 Default: ctrlX CORE" + echo " 10.0.2.2 ctrlX CORE virtual with port forwarding" + echo " " + echo "-ssl-port Port number for HTTPS (SSL) connection" + echo " 443 Default: ctrlX CORE" + echo " 8443 ctrlX CORE virtual with port forwarding" + echo " " + echo "-ssl-usr User name for HTTPS (SSL) connection" + echo " boschrexroth default value" + echo " " + echo "-ssl-pwd Password for HTTPS (SSL) connection" + echo " boschrexroth Default value" + echo " " + echo "-svc Switch scheduler to state Service" + echo " n Do not swtich" + echo " y state=SERVICE -> install snap -> state=OPERATING" + echo " " + echo "-arch CPU architecture" + echo " arm64 Default: CORE M3/4" + echo " amd64 ctrlX CORE virtual, OS" + echo " " + echo "-ssh-port Port number for HTTPS (SSL) connection" + echo " 22 Default: ctrlX CORE" + echo " 8022 ctrlX CORE virtual with port forwarding" + echo " " + echo "-ssh-usr User name for SSH connection" + echo " rexroot Default value" + echo " " + echo " " + echo "-ctrlx-virt-PF Use settings for ctrlX CORE virtual with Port Forwarding" + echo " 10.0.2.2, 8443, amd64, 8022" + echo " " + echo "-ctrlx-virt-NA Use settings for ctrlX CORE virtual with Network Adapter" + echo " 192.168.1.1, 443, amd64, 22" + echo " " + + exit 1 + fi +done + +echo -build = ${BUILD} +echo " " +echo -upload = ${UPLOAD} +echo -addr = ${ADDR} +echo -arch = ${ARCH} +echo -svc = ${SVC} +echo -ssl-port = ${SSL_PORT} +echo -ssl-usr = ${SSL_USR} +echo -ssl-pwd = ${SSL_PWD} +echo " " +echo -logs = ${LOGS} +echo -ssh-port = ${SSH_PORT} +echo " " +echo " " +echo "Settings OK? Waiting" ${SECONDS_TO_WAIT_AFTER_SHOW_ARGUMENTS} "s ..." +read -t ${SECONDS_TO_WAIT_AFTER_SHOW_ARGUMENTS} -p "Press ENTER to continue" + +if grep -q "y" <<<${BUILD} +then + echo " " + echo ----------------------------------------------------------------- + echo Building snap + echo " " + source build-snap-${ARCH}.sh +fi + +if grep -q "y" <<<${UPLOAD} +then + + echo " " + echo ----------------------------------------------------------------- + echo Requesting new Bearer Token + echo " " + + res=$(curl --insecure --no-progress-meter --request POST https://${ADDR}:${SSL_PORT}/identity-manager/api/v1/auth/token --header 'Content-Type: application/json' --data-raw '{"name":"'${SSL_USR}'","password":"'${SSL_PWD}'"}') + # https://stackoverflow.com/questions/9733338/shell-script-remove-first-and-last-quote-from-a-variable + # Remove first and last quote (") from a variable + TOKEN=$(echo ${res} | jq .access_token | xargs) + + echo Bearer ${TOKEN} + echo " " + + + echo " " + echo ----------------------------------------------------------------- + echo Allow installation from unknown source + echo " " + + curl -X PUT \ + https://${ADDR}:${SSL_PORT}/package-manager/api/v1/settings \ + -H 'accept: */*' \ + -H "Authorization: Bearer ${TOKEN}" \ + -H 'Content-Type: application/json' \ + -d '{ "allowUnknownApps": true }' \ + --insecure --no-progress-meter + + if grep -q "y" <<<${SVC} + then + echo " " + echo ----------------------------------------------------------------- + echo Switching Scheduler to state SERVICE + echo " " + + curl -X 'PUT' \ + https://${ADDR}:${SSL_PORT}/automation/api/v1/scheduler/admin/state?format=json \ + -H 'accept: application/json' \ + -H "Authorization: Bearer ${TOKEN}" \ + -H 'Content-Type: application/json' \ + -d '{"state":"SERVICE"}' \ + --insecure --no-progress-meter + fi + + + echo " " + echo ----------------------------------------------------------------- + echo Uploading and installing ${ARCH} snaps + + for f in $(find . -maxdepth 1 -name "*_${ARCH}.snap"); + do + echo " " + echo $f + echo " " + curl -X POST https://${ADDR}:${SSL_PORT}/package-manager/api/v1/packages \ + -H "accept: */*" \ + -H "Authorization: Bearer ${TOKEN}" \ + -H "Content-Type: multipart/form-data" \ + -F "file=@${f}" \ + -F update=true \ + --insecure --no-progress-meter + done; + + echo "Waiting ${SECONDS_TO_WAIT_AFTER_UPLOAD}s after installation ..." + read -t ${SECONDS_TO_WAIT_AFTER_UPLOAD} -p "Wait or press ENTER to continue" + + if grep -q "y" <<<${SVC} + then + + echo " " + echo ----------------------------------------------------------------- + echo Switching Scheduler to state OPERATING + echo " " + + RESPONSE=Error + while grep -q "Error" <<<${RESPONSE} + do + + RESPONSE=$(curl -X 'PUT' \ + https://${ADDR}:${SSL_PORT}/automation/api/v1/scheduler/admin/state?format=json \ + -H 'accept: application/json' \ + -H "Authorization: Bearer ${TOKEN}" \ + -H 'Content-Type: application/json' \ + -d '{"state":"OPERATING"}' \ + --insecure --no-progress-meter) + + if grep -q "Error" <<<${RESPONSE} + then + echo " " + echo WARNING Switching Scheduler to state OPERATING failed + echo "We are repeating in ${SECONDS_TO_WAIT_AFTER_UPLOAD}s ..." + read -t ${SECONDS_TO_WAIT_AFTER_UPLOAD} -p "Wait or press ENTER to continue" + fi + done + + fi + + echo " " + echo ----------------------------------------------------------------- + echo Deleting Bearer Token + echo " " + curl \ + --insecure --no-progress-meter \ + --request DELETE https://${ADDR}:${SSL_PORT}/identity-manager/api/v1/auth/token \ + -H 'accept: */*' -H "Authorization: Bearer ${TOKEN}" + +fi + +SNAP_FILE=$(ls *${ARCH}.snap) +SNAP_VERSION=${SNAP_FILE%_*} +SNAP=${SNAP_VERSION%_*} + +echo Searching ${SNAP} in snap list... + +SNAP_LIST=$(ssh -o StrictHostKeyChecking=no -p ${SSH_PORT} ${SSH_USR}@${ADDR} snap list) +echo " " + +if grep -q "${SNAP}" <<<${SNAP_LIST} +then + echo "Our snap is installed" +else + echo "Our snap is NOT installed!" + read -t ${SECONDS_TO_WAIT_AFTER_UPLOAD} -p "Press Ctrl-C to exit" +fi + +echo " " + +if grep -q "y" <<<${LOGS} +then + echo " " + echo ----------------------------------------------------------------- + echo Viewing logs + echo " " + + ssh -o StrictHostKeyChecking=no -p ${SSH_PORT} ${SSH_USR}@${ADDR} sudo snap logs -f ${SNAP} +fi + + diff --git a/scripts/environment/README-internal.md b/scripts/environment/README-internal.md new file mode 100644 index 00000000..78228872 --- /dev/null +++ b/scripts/environment/README-internal.md @@ -0,0 +1,84 @@ +# Building and Providing a ctrlX Application Build Environment for ctrlX WORKS + +__Important__: + +* The host operating system were the App Builder Environments are running must be Windows 64Bit. + +* The user-image-files (see below) can only be build on a Linux system (e.g. an App Builder Environment). + +## Concept + +__cloud-config-amd64__ and __cloud-config-aarch64__ are so called cloud-config files. These files are compiled into user-data-image files. One for proxy usage, the other for none-proxy usage. + +With the script __user-data-img-build-all.sh__ all user-data-image files are build. + +Remark: The user-data-image files for aarch64 are kept for future usage. + +__Important: The user-data-image files for amd64 are used by ctrlX WORKS.__ + +For more information see [cloud-init](https://cloud-init.io/) + +## Files + +### cloud-config Files + +Cloud-config files are containing settings (user/password, proxy,...) and a list of packages to be installed on the App Builder Environment: + +* cloud-config-amd64 For amd64 VMs +* cloud-config-aarch64 For aarch64 VMs (reserved) + +For informations on the content of cloud-config files see [Cloud config examples](https://cloudinit.readthedocs.io/en/latest/topics/examples.html). + +### User Image Files + +cloud-config file are compiled into image files: + +* ubuntu-20.04-server-cloudimg-amd64-user-data-proxy.img amd64 VM with proxy usage +* ubuntu-20.04-server-cloudimg-amd64-user-data-noproxy.img amd64 VM without proxy usage +* ubuntu-20.04-server-cloudimg-aarch64-user-data-proxy.img aarch64 VM with proxy usage +* ubuntu-20.04-server-cloudimg-aarch64-user-data-noproxy.img aarch64 VM without proxy usage + +### Linux Scripts + +* user-data-img-build.sh, user-data-img-build-all.sh are used to compile the cloud-config files into user-data-image files. + +### Windows Batch Files + +* __scp_id_rsa.bat__ copies the id_rsa and id_rsa.pub file from the Windows host to the App Builder Environment guest operating system so that entering password on login is obsolete. + +* __ssh-keygen-copy-id.bat__ enables login without password by adding .ssh\id_rsa.pub of the host to ~/.authorized_keys of the QM VM. + +* __shrink-qcow2.bat__ shrinks the qcow2 snapshot file. + +!!! important + This action takes some time, do not interrupt. + +* wget.bat calls PowerShell to download files. + +### Folder install-scripts + +Contains shell scripts packed into the cloud-config files. + +## License + +MIT License + +Copyright (c) 2021-2022 Bosch Rexroth AG + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/scripts/install-sdk-from-github.sh b/scripts/install-sdk-from-github.sh new file mode 100644 index 00000000..d1e538c6 --- /dev/null +++ b/scripts/install-sdk-from-github.sh @@ -0,0 +1,155 @@ +#!/usr/bin/env bash + +TIME_PROMPT=10 + +DEST_DIR=ctrlx-automation-sdk +ZIP_ARCHIVE=ctrlx-automation-sdk-*.zip +ZIP_DIR=UNZIPPED_IZqkx4cTqamJikhsXfq5 +DEP_PACKAGE=*.deb + +MY_DIR=$(pwd) + +if [ -d "$DEST_DIR" ]; +then + echo " " + echo "-----------------------------------------------------------------------" + echo "Deleting existing directory ${DEST_DIR}" + read -t $TIME_PROMPT -p "Waiting ${TIME_PROMPT}s - Press ENTER to continue or Ctrl-C to exit" + sudo rm -rf $DEST_DIR +fi + +if ls $ZIP_ARCHIVE 1> /dev/null 2>&1; then + echo " " + echo "-----------------------------------------------------------------------" + echo "Deleting existing zip file(s) ${ZIP_ARCHIVE}" + read -t $TIME_PROMPT -p "Waiting ${TIME_PROMPT}s - Press ENTER to continue or Ctrl-C to exit" + rm $ZIP_ARCHIVE +fi + +echo " " +echo "-------------------------------------------" +echo " " +git clone https://github.com/boschrexroth/ctrlx-automation-sdk.git + +#LATEST=$(curl -s -u USER:TOKEN https://api.github.com/repos/boschrexroth/ctrlx-automation-sdk/releases/latest) +LATEST=$(curl -s https://api.github.com/repos/boschrexroth/ctrlx-automation-sdk/releases/latest) + +if grep -q "limit exceeded" <<<${LATEST}; then + echo " " + echo ERROR + echo " " + echo ${LATEST} + echo " " + echo "Hint:" + echo This error happens often because a proxy server is used. + echo In this case github registered a hugh number of requests from the same machine. + echo " " + echo Workaround: + echo "- Open/Register your user account on github" + echo "- Create a user token" + echo "- Add user:token to the curl command above: curl -s -u USER:TOKEN ..." + exit 1 +fi + +# .assets[0].browser_download_url --> ctrlx-...zip +# .assets[1].browser_download_url --> ctrlx-...deb +sudo apt-get install jq -y +DOWNLOAD_URL=$(echo $LATEST | jq -r .assets[0].browser_download_url) + +echo " " +echo "------------------------------------------------------" +echo "Downloading latest ctrlx-automation-sdk zip archive..." +echo " " +wget $DOWNLOAD_URL +echo " " + +if compgen -G ${ZIP_ARCHIVE} > /dev/null; then + echo Done +else + echo "ERROR Could not download ${ZIP_ARCHIVE} does not exist" + exit 1 +fi + +echo " " +echo "------------------------------------------------------" +echo "Unzipping ctrlx-automation-sdk zip archive..." +echo " " + +# Get subdirectories of github repo +DIRS_UNDER_GITHUB=$(ls -d ${DEST_DIR}/*/) + +# Create temp dir for unzip +sudo rm -rf ${ZIP_DIR}/ +mkdir $ZIP_DIR +cd $ZIP_DIR + +unzip -xK $(ls ../${ZIP_ARCHIVE}) + +# Remove unzipped dirs of zip archive already stored in github repo +sudo rm -rf $DIRS_UNDER_GITHUB + +cd $DEST_DIR + +# Get list of remaining dirs to be moved to github dir +DIRS_IN_ZIP=$(ls -d */) + +for DIR in $DIRS_IN_ZIP +do + mv "$DIR" ${MY_DIR}/${DEST_DIR} +done + +sudo rm -rf ${ZIP_DIR}/ +rm ${MY_DIR}/$ZIP_ARCHIVE + +echo " " +echo "------------------------------------------------------" +echo "Setting x permissions..." +echo " " + +cd ${MY_DIR}/${DEST_DIR} + +chmod a+x bin/oss.flatbuffers*/ubuntu20-gcc-*/release/flatc +chmod a+x bin/framework/ubuntu20-gcc-*/rexroth-automation-frame +chmod a+w -R include +sudo chown -R boschrexroth:boschrexroth fbs/comm/ethercat/master/ +sudo chown -R boschrexroth:boschrexroth bfbs/comm/ethercat/master/ +sudo chmod 777 -R fbs/comm/ethercat/master/ +sudo chmod 777 -R bfbs/comm/ethercat/master/ +find . -name '*.sh' -exec chmod +x {} \; + +cd deb/ + + +echo " " +echo "------------------------------------------------------" +echo "Installing debian package ${DEP_PACKAGE}..." +echo " " + +if compgen -G ${DEP_PACKAGE} > /dev/null; then + + # Install package containing required component dpkg-scanpackages + sudo apt-get install dpkg-dev + + # Install debian package locally so that 'apt-get install' will find it (for building sample project snaps) + dpkg-scanpackages -m . > Packages + + # Create full path + FULL_PATH=$(pwd) + # Add package to sources list + sudo sh -c "echo 'deb [trusted=yes] file:${FULL_PATH} ./' > /etc/apt/sources.list.d/ctrlx-automation.list" + # Use newest sources list + sudo apt update + + # Install newest ctrlx-datalayer package + sudo apt-get install -y ctrlx-datalayer +else + echo "ERROR ${DEP_PACKAGE} not found!" +fi + +echo " " +echo "------------------------------------------------------" +echo "Installing snapcraft..." +echo " " + +sudo snap install snapcraft --classic +