Itaque earum rerum hic tenetura sapiente delectus,
-Itaque earum rerum hic tenetura sapiente delectus,
-Itaque earum rerum hic tenetura sapiente delectus,
-Itaque earum rerum hic tenetura sapiente delectus,
-In ullamcorper est eget tempor cursus neque mi consectetuer mi a ultricies massa est sed nisl Class aptent taciti sociosqu ad litora torquent per conubia nostra
-In ullamcorper est eget tempor cursus neque mi consectetuer mi a ultricies massa est sed nisl Class aptent taciti sociosqu ad litora torquent per conubia nostra
-In ullamcorper est eget tempor cursus neque mi consectetuer mi a ultricies massa est sed nisl Class aptent taciti sociosqu ad litora torquent per conubia nostra
--There are various ways to get involved via GitHub : -https://github.com/eclipse-thingweb - -
--You can pick one of the Eclipse Thingweb components such as node-wot or playground and start using them. -Even better, you can contribute to their source code! -Below are some examples of what you can contribute with: -
-- All Thingweb components are licensed with Eclipse Public License v. 2.0 and W3C Software Notice and Document License (2015-05-13). You can pick the one that suits your requirements (i.e. you only have to comply with one, not both). -
- - - - - diff --git a/content/hands-on-exposed-thing-guide.md b/content/hands-on-exposed-thing-guide.md deleted file mode 100644 index 6b8a7f1..0000000 --- a/content/hands-on-exposed-thing-guide.md +++ /dev/null @@ -1,173 +0,0 @@ ---- -title: "Exposed Thing with node-wot as Dependency" -draft: false ---- - -# Exposed Thing with node-wot as Dependency - -## Introduction - -In this document, we aim to introduce how to use the node-wot libraries to implement an Exposed Thing. -Differently from the [Thingweb Hands-on](http://www.thingweb.io/hands-on.html), here we will show to use TypeScript along with node-wot as an npm dependency rather than cloning a GitHub repository. -The aim is to establish an easy-to-understand and reusable template that can be used to implement any Exposed Thing. -Some devices that use this template can be found [here](https://github.com/tum-esi/wot-sys/tree/master/Devices). - -Using TypeScript gives type safety and the separation of source and build directories. -Using node-wot as an npm dependency allows faster installation and also being able to install only what is needed for the given project. -For example, this way one can install only the CoAP binding if the device will only communicate with CoAP. - -The source files can be found [at the examples folder of node-wot](https://github.com/eclipse-thingweb/node-wot/tree/master/examples/templates/exposed-thing). You should modify this code to match your needs. - -## Code Structure - -The structure can be seen in two parts: - -- `index.js` that is run with `npm run start` where the different protocol bindings and parameters such as a TD directory address is added. In this file one would expect to see no device specific libraries or logic. For example, if you are moving a robot from left to right, a handler for this action should not be present. Once the `index.js` is set up, there should not be any need to edit this file, the work should continue in the `src` folder. -- `src` folder is where the TypeScript sources are found. Upon running `npm run build` the contents of this folder will be transcompiled into JavaScript and will be found in `dist` folder. The TypeScript file `src/base.ts` is where the actual logic of the Exposed Thing is. In this file, we add the TD, different interaction affordances, handlers and TD registration. - -We can thus summarize it like: - -- `index.js`: Starting point of the Exposed Thing, analogous to `index.html` of websites. This is also common practice for npm packages. -- `src` folder: Logic of the Exposed Thing in TypeScript source format -- `dist` folder: Transcompiled logic of the Exposed Thing in JavaScript source format that is used by `index.js` -- `package.json`: npm dependencies of the Exposed Thing project. Here you will find the different protocol bindings. - -## Code Explanation - -Here, we will explain what every (or most!) of the lines do. If you just want to use it, skip to [What to change and get running](#what-to-change-and-get-running). - -### package.json - -- devDependencies (lines 12-17): These are the dependencies that will be used during development time. -Most importantly, `wot-typescript-definitions` is needed in order for TypeScript to understand what is `WoT`, `ExposedThing` etc. - -{{< highlight js >}} -{ - ... - "devDependencies": { - "typescript": "3.3.1", - "wot-typescript-definitions": "0.8.0-SNAPSHOT.22", //update this accordingly - "@types/node": "11.9.4", - "tslint": "5.12.1" - } - ... -} -{{< / highlight >}} - -- dependencies (lines 18-23): These are dependencies that will be used in development and runtime. -Here you will put the bindings that are required. `@node-wot/core` is always needed so that functions like `produce()`, `start()` are available. -We also use the [request](https://www.npmjs.com/package/request) library for registration of the TD to a directory via HTTP and the [ajv](https://www.npmjs.com/package/ajv) for validation of inputs with the DataSchema of the TD. -Below is an example with the HTTP binding, but you can change it to [CoAP](https://www.npmjs.com/package/@node-wot/binding-coap) or [MQTT](https://www.npmjs.com/package/@node-wot/binding-mqtt) or anything else that node-wot supports. - -{{< highlight js >}} -{ - ... - "dependencies": { - "@node-wot/binding-http": "0.8.0", //update this accordingly - "@node-wot/core": "0.8.0", //update this accordingly - "request": "2.88.0", - "ajv": "^6.10.2" - } - ... -} -{{< / highlight >}} - -- scripts (lines 25-30): These are the scripts that are used to build, run and clean the repository. -Other than the `clean` script, they are cross-platform, i.e. can run on Linux, macOS or Windows. - -- others: You can also change your package name, description, author, license etc. and adapt to your needs. - -### index.js - -`index.js` is the entry point of the script. Here we create and add the necessary servers such as HTTP, CoAP or MQTT to the servient and then start it. -Upon start, a WoT object will be created and passed to the `base.ts` (or `base.js` when transcompiled) where the actual device implementation is. - -- `WotDevice = require("./dist/base.js").WotDevice` (line 2) links to the actual device implementation. In case you change `base.ts` with another name, you should adapt this line. -- `const TD_DIRECTORY = ""` (line 9) specifies the TD directory URI. You can comment it out to remove the registration function. -- `Servient = require("@node-wot/core").Servient` (line 12) and `var servient = new Servient();` (line 25) are responsible for creating a servient. Then different servers (bindings) can be added before starting it. A servient can even contain multiple exposed things. -- Bindings: Lines 14-16, 19-21 and 27-29 does linking, creating and adding of different bindings to the servient, respectively. If you want to change the bindings, you can comment them out. For each binding, the `package.json` file should be also changed and `npm install` should be run to ensure that the dependencies are installed. A change on the bindings should not cause any change in the `base.ts` file. -- Starting the servient (lines 31-33): After starting the servient, which does nothing without any ExposedThing, exposed thing(s) should be added. As you can see in line 32, this is where we make the reference to the `WoTDevice` created in the second line. You can add more than one `WoTDevice` (could be called anything). node-wot puts multiple ExposedThings under one servient differentiating them by their names. Thus, one can have `http://localhost:8080/counter/` and `http://localhost:8080/mywotdevice/` served from the servient. - -### base.ts - -This is where the logic of the ExposedThing is implemented and its TD can be seen. - -- WoT object: The WoT object allows the use of methods such as `produce()` which are used with a servient. As it can be seen, in `base.ts` there is no link to a servient that is created in the `index.js` file and used to pass a WoT object. Similar to the CLI, this file relies on the WoT object which is defined using the `wot-typescript-definitions` in line 15. -- Request and TD registration: [request](https://www.npmjs.com/package/request) is a very simple library for HTTP requests. In this script, we use it to send an HTTP POST request to a TD directory with its TD as the payload. When the ExposedThing is exposed, in line 102 the register method is called with its TD. Lines 107-122 implement the registration methods to the given TD Directory address. We wait 10 seconds before trying again, which recursively calls itself, meaning that every 10 seconds it will try to register its TD. If the `TD_DIRECTORY` is not defined in `index.js` this method will not be executed. -- JSON Schema Validation: We use [ajv](https://www.npmjs.com/package/ajv) for JSON Schema validation, which is to this date the fastest and the most up-to-date JSON Schema validation library in npm. You can use it in the handlers of action invokes or property writes in order to validate the data sent by the Consumer. In order to use ajv, we include it in line 19 and instantiate in line 20. How it can be used is seen in line 182 where an invalid data is responded with "Invalid input" error. -- WoTDevice class: WoTDevice gets the WoT object from the servient and TD Directory address for its constructor. It has attributes `thing`, `deviceWoT` and `td`. `thing` is instantiated as a result of the `produce()` method in lines 88-91. `td` is available from an ExposedThing using the `getThingDescription()` method. To avoid multiple calls to this method, we save it as the `td` attribute. `deviceWoT` attribute is assigned from the `WoT` argument passed in the constructor is used for instantiating everything. Once the constructor gets an ExposedThing, methods for initializing different interaction affordances are called, such as `initializeProperties()`. -- Thing Description: `WoT.produce()` takes as TD as argument and returns an ExposedThing. In this script, we use a TD with 1 property, 1 action and 1 event in order to demonstrate scripting for all interaction affordances. They are all named `myX` with X being an Interaction Affordance like property, action or event. -- Property Declarations (line 77): Here we add all needed properties as class members. Because we have one property `"myProperty"`, we add a corresponding private member `myProperty` -- `initializeProperties()` method (line 164): This method exists in order to cleanly separate where the property handlers are created versus where they are assigned to properties. In this method, we define the properties of the `WotDevice` as class members, set their initial values and assign their corresponding read and write handlers. - - In line 166, we assign private class member `myProperty` the initial value `""`. - - In line 167, we set the corresponding `readPropertyHandler` by assigning the corresponding `myPropertyReadHandler`, defined in line 124, as its callback. - - If the property is writable, we similarly call the method `setPropertyWriteHandler` and assign the `myPropertyWriteHandler` method as its callback -- `initilizeActions()` method (line 171): This method exists in order to cleanly separate where the action handlers are created versus where they are assigned to actions. For an action with input data, the input validation would also happen here. By assigning to invoke handler to `this.myActionHandler`, we call a specific action invoke handler that can be easily encapsulated, allowing easy reusability. -- Line 95: We do not call add an initialization method for events, because events do not need handlers and can be emitted from anywhere (see `myActionHandler` method for an example) -- `myPropertyReadHandler()` (line 124): This is read-handler that can be called from any `setPropertyReadHandler`. The logic of reading, like reading a GPIO pin, should happen here. The value of the property will be then returned in `return this.myProperty`. Use of async-await allows easier programming of asynchronous operations happening inside a property handler. -- `myPropertyWriteHandler()` (line 129): This is write-handler that can be called from any `setPropertyWriteHandler`. The logic of writing, like assigning the input data to the corresponding variable, should happen here. This is where you also should call the `emitPropertyChange` method to signal that there is a change to your property if needed. Use of async-await allows easier programming of asynchronous operations happening inside a property handler. -- `myActionHandler()` (line 134): This is action invoke handler that can be called from any `setActionHandler`. The logic of the action handling, like rotating a robot arm, should happen here. The result of the action will be then returned in `return outputData`. Note that there should be no `outputData` returned if the action has no `output` member. Also, we demonstrate how to emit an event in line 148. Use of async-await allows easier programming of asynchronous operations happening inside an action handler. - -## What to change and get running - -If you don't need to understand everything in the code, just make sure you do the following at least before installing, building and running: - -- `package.json`: - - Change `package.json` to include the bindings you want, e.g. add `"@node-wot/binding-coap": "0.8.0",` to dependencies. - - Change npm related information such as `name`, `version` etc. -- `index.js`: - - Add the required bindings in `index.js` in 3 locations: - - `CoapServer = require("@node-wot/binding-coap").CoapServer` (line 15) - - `var coapServer = new CoapServer({port: 5683});` (line 20) - - `servient.addServer(coapServer);` (line 28) - - Change or remove the TD_DIRECTORY value in `index.js` (line 9) -- `base.ts`: - - Change the TD passed to `this.WoT.produce()` method in line 28 - - Add member variables that will act as properties, like in line 78 - - Write a property-read-handler for different properties, like in line 124 - - Write a property-write-handler for different properties, like in line 131 - - Write an action-invoke-handler for different actions, like in line 144 - - Decide when to emit events and adapt `listenToMyEvent()` in line 162 if needed - - Adapt `initializeProperties` of line 171: - - Assign the starting value for each property - - Set the Read Property handler for each property by adapting line 125 for you property. - - Adapt `initializeActions()` of line 178: - - set an Action Handler for each action you have, like in lines 180-190. You can use `ajv` for input validation. - -### Installation and Running - -- Get the latest node.js: - -```bash -# Using Ubuntu -curl -fsSL https://deb.nodesource.com/setup_17.x | sudo -E bash - -sudo apt-get install -y nodejs -``` - -You will need to change 10.x to a newer version if needed - -- To install dependencies: `npm install` -- To build (transcompiling Typescript to JavaScript): `npm run build` -- To run the code: `npm run start` - -## Change from Version 0.7.X to 0.8.X for Exposed Things - -Version 0.8.X handles properties and interaction inputs differently than previous versions. Below is the list of changes: - -- Properties are not handled internally by node-wot anymore. Property handlers need to read and write to variables or class members that are explicitly defined in the code for the Exposed Things -- The value of interaction inputs cannot be accessed directly. `WoT.InteractionInput` objects have a member function `value()` that returns a promise that will resolve to the value of the input when available. You can either use `input.value().then(...)` or `await input.value()` in an `async` function. - -## Change from Version 0.6.X to 0.7.X for Exposed Things - -Resulting from the discussions in the Scripting API, the API has changed on 28.10.2019. This was a rather big change that also resulted changes in node-wot. Below is a list of changes: - -- You need to pass a full TD (but without forms) as argument to the `produce()` method. Before only non interaction information were passed. -- You cannot do `myExposedThing.td` and have to pass through `myExposedThing.getThingDescription()` -- `WoTFactory` is replaced by `WoT` in `wot-typescript-definitions`. You thus see `WoT.produce()` instead of `thingFactory.produce()` -- Since you pass a whole TD to `produce()` method, you don't need `addProperty`, `addAction` and `addEvent`. -- Instead of `this.thing.events[myEvent].emit(myPayload);` there is `this.thing.emitEvent(myEvent,myPayload);` -- You have to use `setActionHandler` whereas before you could assign the handler in the `addAction` like `addAction(name,metadata,handler)`. -- Since you cannot pass the initial value for a property with `addProperty`, you have to do a `writeProperty(myInitialValue)` _at some point_. -- You cannot change the TD of an ExposedThing, i.e. you cannot do `thing.id="thingweb:io:example"`. - -You can see a git diff [here](https://github.com/tum-esi/wot-sys/commit/6cef8530b3317d98c2a7dea389c92ba2786be892#diff-0d33955cb472f41f07397fc2687c6425R10) diff --git a/content/hands-on-intro-raspberry.md b/content/hands-on-intro-raspberry.md deleted file mode 100644 index 7b1ffb9..0000000 --- a/content/hands-on-intro-raspberry.md +++ /dev/null @@ -1,360 +0,0 @@ ---- -title: "WoT - Introduction & Raspberry Pi Setup" -draft: false ---- - -# WoT - Introduction & Raspberry Pi Setup - -This document aims to introduce the Web of Things (WoT) as building blocks for applications based on the IoT devices. -As a growing area, IoT services and application have a huge potential. -From home automation to smart-grid passing by industrial manufacturers, IoT is gaining popularity as a potential solution to address their need. -Several technologies can be used to build an IoT application mainly because of the specific constraints of the devices. -This creates interoperability challenges for communication between devices. -WoT offers an approach to expose and consume IoT resources as web resources. - -WoT is an initiative by the W3C to apply on the IoT device the same principles as for the existing web resources across the Internet. -The main idea behind WoT is exposing virtual or physical devices as a resource with a description of its capabilities. -That resource can then be accessed from a browser or another device in the same manner as a web page. -WoT is not a proposition for a new communication protocol between devices, it uses existing protocols to communicate with the devices according to their communication capabilities. -It presents a set of architectural and programming patterns for building interoperable devices based on the following three fundamentals: - -+ Uniform Resource Identifier (URI) for identifying devices and their descriptions -+ A wide variety of existing protocols for accessing the devices -+ A description of the description as metadata used both for interoperability and presentability purposes - -## WoT Architecture - -The central component of the WoT architecture is "WoT Servient" which is functional virtual device. -A Servient extends the IoT physical devices by providing standard access and control capabilities to the devices. - - - -A Servient provides a protocol agnostic runtime for the application using the resource model. -Servient application uses this resource model which enables interoperability with other Servients and users that are using multiple bindings. -Servient may act at the same time as a client and a server according to the applications' behavior. -The resources associated to a Servient instance are described in a Thing description. -It uses JSON-LD to make this description readable by both humans and machines. -Such a description enhances the machine to machine communication and makes the Things ready for the Semantic Web. - - - -A Servient instance can run on multiple platforms at different layer of the IoT network. -It can be deployed inside the IoT device itself in condition to have a minimum processing power. -It may also be deployed inside a smart hub or edge node to adapt legacy devices to the architecture. -This adaptation role can also be provided by a Servient deployed on the cloud. -Last but not least, Servient instances can be accessed as web resources by a smartphone and web browsers. - -# Setup the Raspberry Pi Zero W - -We assume that the Raspberry Pi used is a freshly installed one with Debian. -First, it needs to be configured for a network connection. -Second, the environment needs to be configured mainly by installing Node.js and a few other dependencies. -Finally, things-web needs to be installed on the system. - -### Network configuration - -Insert the SD card into your card reader and create the two following files as illustrated in the image below: - - - - -wpa_supplicant.conf: is the file that is used to configure your WiFi on the command line. -This file must contain the following configuration where **######** is your WiFi password: - -{{< highlight bash "linenos=table" >}} -country=US -ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev -update_config=1 -network={ - ssid="IoT-testbed-2.4" - psk="#########" - key_mgmt=WPA-PSK - proto=RSN - pairwise=CCMP - group=CCMP - auth_alg=OPEN -} -{{< / highlight >}} - -### Installing Node.js -Ideally, Node.js 10 should be installed. -It works also with Node.js 8 but Node.js 10 is highly recommended. -To install the Node.js version 10, make sure that the right architecture is used. -Below the commands for the Raspberry Pi Zero W: - - - - -{{< highlight bash >}} -wot@node-wot:~$ wget https://nodejs.org/dist/v10.15.0/node-v10.15.0-linux-armv6l.tar.xz -wot@node-wot:~$ sudo mkdir /usr/local/lib/nodejs -wot@node-wot:~$ sudo tar -xJvf node-v10.15.0-linux-armv6l.tar.xz -C /usr/local/lib/nodejs -wot@node-wot:~$ sudo mv /usr/local/lib/nodejs/node-v10.15.0-linux-armv6l /usr/local/lib/nodejs/node-v10.15.0 -wot@node-wot:~$ nano ~/.profile -{{< / highlight >}} - - -Inside the **~/.profile**, add the following: - -{{< highlight bash >}} -export NODEJS_HOME=/usr/local/lib/nodejs/node-v10.15.0/bin -export PATH=$NODEJS_HOME:$PATH -{{< / highlight >}} - -. - -{{< highlight bash >}} -wot@node-wot:~$ . ~/.profile -wot@node-wot:~$ node -v -wot@node-wot:~$ npm version -{{< / highlight >}} - - - - - - - - - -### Cloning the repository - -The reference implementation of the Web of Things is published in GitHub as node-wot project at [GitHub](https://github.com/eclipse-thingweb/node-wot). -The project is part of the Eclipse Foundation. -Use the command below to clone the repository on your local system: - -{{< highlight bash >}} -wot@node-wot:~$ sudo apt install git -wot@node-wot:~$ git clone https://github.com/eclipse-thingweb/node-wot -{{< / highlight >}} - - - - - -### Installation - -The installation process is composed of mainly two steps. -The first step installs the Node.js dependences. -The second step installs and builds the node-wot project. - -#### Installing the packages - -Node-wot requires dependencies such as Typescript, lerna, etc. -By running the command below, those dependencies are installed: - -{{< highlight bash >}} -wot@node-wot:~$ cd node-wot -wot@node-wot:~$ npm install -{{< / highlight >}} - - - - -#### Building the libraries - -As the node-wot project is mainly developed using Typescript, `tsc` command needs to be executed to trans-compile that code to JavaScript. -The command below builds the project and its packages: - - -{{< highlight bash >}} -wot@node-wot:~$ npm run build -{{< / highlight >}} - - - - -#### Running the example Servient - -Run the command below to expose a "server" Servient: - -{{< highlight bash >}} -wot@node-wot:~$ node packages/cli/dist/cli.js examples/scripts/counter.js -{{< / highlight >}} - -You can access the Thing Description generated at http://localhost:8080/counter. - - - -## Thing Description - -The Thing Description (TD) is one major element of the web of Things approach. -It is a JSON or JSON-LD object that describes a Thing. -As illustrated below, it describes aspects such as name, description, list of accessible properties and list of available actions. - - - -### Properties - -The property section describes interesting information about the exposed property as illustrated below. -It offers also the "href" that defines the URI that the client can use to access this property as a resource. - - - -### Actions - -The actions section describe the actions exposed by the Thing. -They enable a client to remotely invoke the function associated to this action. -Like for the properties, the actions expose an "href" URI that can be used to invoke those actions as illustrated below: - - - -### Standard description - -The full list of the elements that can be used in a TD is available in the W3C document at https://www.w3.org/TR/wot-thing-description/. - -Once you create a Servient using the reference implementation, a TD respecting the standard is automatically generated for your exposed Thing. -The next section describes how to create a Servient and access its TD. - -## A Servient - -Web of Things programming model is based on the notion of "Servient". -A Servient is a program developed using the WoT Scripting API and can behave at the same time as a server and a client. -For example, a Servient can be a client for a field device (light bulb) and server for the mobile application that is used to control that device. - -### Servient’s structure - -As previously stated, a Servient can be both a client and a server. -The structure of a Servient varies depending on the target behavior. -However, it is centered on the Thing Description. -To expose a new Thing (server mode), you need first to create the Thing by passing some metadata to the Scripting API as illustrated below: - -{{< highlight js "linenos=table" >}} -WoT.produce({ - title: "counter", - description: "counter example Thing", - "@context": "https://www.w3.org/2019/wot/td/v1", - properties: { - count: { - type: "integer", - description: "current counter value", - observable: true, - readOnly: true, - } - }, - actions: { - increment: { - description: "Incrementing counter value", - uriVariables: { - step: { type: "integer", minimum: 1, maximum: 250 }, - }, - } - } -}) - .then((thing) => { - console.log("Produced " + thing.getThingDescription().title); - - // init property values - // ... - // set property handlers - // ... - // set action handlers - // ... - - // expose the thing - thing.expose().then(() => { - console.info(thing.getThingDescription().title + " ready"); - }); - }) - .catch((e) => { - console.log(e); - }); -{{< / highlight >}} - -This code initiates the creation of a Thing named "counter" with its interactions and adds metadata such as context to that Thing. - -This will create the property, so it can be exposed and accessed both using the Scripting API and using a binding (by default, the HTTP, and CoAP bindings are used to expose Things on node-wot). - -Once your run the Servient, the exposed property will be accessible at http://localhost:8080/counter/properties/count as illustrated below: - - - - -Before we expose properties/actions/events, we need to add handlers (e.g., an action handler is added as described below). - -{{< highlight js "linenos=table" >}} -thing.setActionHandler("increment", async (params, options) => { - let step = 1; - if (options && typeof options === "object" && "uriVariables" in options) { - if ("step" in options.uriVariables) { - const uriVariables = options.uriVariables as Record- Eclipse Thingweb provides services to support Web of Things developers. - These services are listed below. -
- - -- Playground is a tool to validate TDs and manipulate them for usage in other tools. - You can do validation to check conformance, generate Open API and Async API documents, add or remove default values, visualize TDs and find spelling mistakes in TDs. -
- -- Using the tools below, you can interact with different WoT Things over your browser. -
- -
- Eclipse Thingweb hosts Things that can be interacted with over the public Internet.
- You can use them to test your WoT applications.
- Note: we also offer the test-things repository with a collection of IoT device simulators that can be used for testing and exploration purposes of different protocols and other Web of Things mechanisms.
-
- All of them require no security mechanism to be communicated with and have same behavior from CoAP or HTTP endpoints. - Below are small explanations on what they can be used for: -
- -- Additionally, Counter and Smart Coffee Machine offer simple UIs that reflect their state: -
-Copyright © ${new Date().getFullYear()} Eclipse Thingweb. Built with Docusaurus.
+ `, + }, + prism: { + theme: prismThemes.github, + darkTheme: prismThemes.vsDark, + }, + }), +}; + +export default config; diff --git a/hands-on/articles/_category_.json b/hands-on/articles/_category_.json new file mode 100644 index 0000000..74f8384 --- /dev/null +++ b/hands-on/articles/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "Web of Things - Hands-On", + "className": "hands-on-articles", + "position": 1, + "link": { + "type": "generated-index", + "slug": "articles", + "description": "This section aims to provide hands-on information about the Web of Things (WoT) in general and the technologies developed in this area. For more information please visit the following sub-pages:" + } +} \ No newline at end of file diff --git a/hands-on/articles/exposed-thing.md b/hands-on/articles/exposed-thing.md new file mode 100644 index 0000000..d89c816 --- /dev/null +++ b/hands-on/articles/exposed-thing.md @@ -0,0 +1,189 @@ +--- +sidebar_position: 2 +title: Exposed Thing with node-wot as Dependency +description: In this document, we aim to introduce how to use the node-wot libraries to implement an Exposed Thing. +--- +# Exposed Thing with node-wot as Dependency + +## Introduction + +In this document, we aim to introduce how to use the node-wot libraries to implement an Exposed Thing. Differently from the Thingweb Hands-on, here we will show to use TypeScript along with node-wot as an npm dependency rather than cloning a GitHub repository. The aim is to establish an easy-to-understand and reusable template that can be used to implement any Exposed Thing. Some devices that use this template can be found here. + +Using TypeScript gives type safety and the separation of source and build directories. Using node-wot as an npm dependency allows faster installation and also being able to install only what is needed for the given project. For example, this way one can install only the CoAP binding if the device will only communicate with CoAP. + +The source files can be found at the examples folder of node-wot. You should modify this code to match your needs. + +## Code Structure + +The structure can be seen in two parts: + +* index.js that is run with npm run start where the different protocol bindings and parameters such as a TD directory address is added. In this file one would expect to see no device specific libraries or logic. For example, if you are moving a robot from left to right, a handler for this action should not be present. Once the index.js is set up, there should not be any need to edit this file, the work should continue in the src folder. + +* src folder is where the TypeScript sources are found. Upon running npm run build the contents of this folder will be transcompiled into JavaScript and will be found in dist folder. The TypeScript file src/base.ts is where the actual logic of the Exposed Thing is. In this file, we add the TD, different interaction affordances, handlers and TD registration. + +We can thus summarize it like: + +* index.js: Starting point of the Exposed Thing, analogous to index.html of websites. This is also common practice for npm packages. +* src folder: Logic of the Exposed Thing in TypeScript source format +* dist folder: Transcompiled logic of the Exposed Thing in JavaScript source format that is used by index.js +* package.json: npm dependencies of the Exposed Thing project. Here you will find the different protocol bindings. + +## Code Explanation + +Here, we will explain what every (or most!) of the lines do. If you just want to use it, skip to What to change and get running. + +### package.json + +* devDependencies (lines 12-17): These are the dependencies that will be used during development time. Most importantly, wot-typescript-definitions is needed in order for TypeScript to understand what is WoT, ExposedThing etc. + +```js +{ + ... + "devDependencies": { + "typescript": "3.3.1", + // highlight-next-line + "wot-typescript-definitions": "0.8.0-SNAPSHOT.22", //update this accordingly + "@types/node": "11.9.4", + "tslint": "5.12.1" + } + ... +} +``` + +* dependencies (lines 18-23): These are dependencies that will be used in development and runtime. Here you will put the bindings that are required. @node-wot/core is always needed so that functions like produce(), start() are available. We also use the request library for registration of the TD to a directory via HTTP and the ajv for validation of inputs with the DataSchema of the TD. Below is an example with the HTTP binding, but you can change it to CoAP or MQTT or anything else that node-wot supports. + +```js +{ + ... + "dependencies": { + "@node-wot/binding-http": "0.8.0", //update this accordingly + // highlight-next-line + "@node-wot/core": "0.8.0", //update this accordingly + "request": "2.88.0", + "ajv": "^6.10.2" + } + ... +} +``` + +* scripts (lines 25-30): These are the scripts that are used to build, run and clean the repository. Other than the clean script, they are cross-platform, i.e. can run on Linux, macOS or Windows. + +* others: You can also change your package name, description, author, license etc. and adapt to your needs. + +### index.js + +index.js is the entry point of the script. Here we create and add the necessary servers such as HTTP, CoAP or MQTT to the servient and then start it. Upon start, a WoT object will be created and passed to the base.ts (or base.js when transcompiled) where the actual device implementation is. + +* WotDevice = require("./dist/base.js").WotDevice (line 2) links to the actual device implementation. In case you change base.ts with another name, you should adapt this line. +* const TD_DIRECTORY = "" (line 9) specifies the TD directory URI. You can comment it out to remove the registration function. +* Servient = require("@node-wot/core").Servient (line 12) and var servient = new Servient(); (line 25) are responsible for creating a servient. Then different servers (bindings) can be added before starting it. A servient can even contain multiple exposed things. +* Bindings: Lines 14-16, 19-21 and 27-29 does linking, creating and adding of different bindings to the servient, respectively. If you want to change the bindings, you can comment them out. For each binding, the package.json file should be also changed and npm install should be run to ensure that the dependencies are installed. A change on the bindings should not cause any change in the base.ts file. +* Starting the servient (lines 31-33): After starting the servient, which does nothing without any ExposedThing, exposed thing(s) should be added. As you can see in line 32, this is where we make the reference to the WoTDevice created in the second line. You can add more than one WoTDevice (could be called anything). node-wot puts multiple ExposedThings under one servient differentiating them by their names. Thus, one can have http://localhost:8080/counter/ and http://localhost:8080/mywotdevice/ served from the servient. + +### base.ts + +This is where the logic of the ExposedThing is implemented and its TD can be seen. + +* WoT object: The WoT object allows the use of methods such as produce() which are used with a servient. As it can be seen, in base.ts there is no link to a servient that is created in the index.js file and used to pass a WoT object. Similar to the CLI, this file relies on the WoT object which is defined using the wot-typescript-definitions in line 15. +* Request and TD registration: request is a very simple library for HTTP requests. In this script, we use it to send an HTTP POST request to a TD directory with its TD as the payload. When the ExposedThing is exposed, in line 102 the register method is called with its TD. Lines 107-122 implement the registration methods to the given TD Directory address. We wait 10 seconds before trying again, which recursively calls itself, meaning that every 10 seconds it will try to register its TD. If the TD_DIRECTORY is not defined in index.js this method will not be executed. +* JSON Schema Validation: We use ajv for JSON Schema validation, which is to this date the fastest and the most up-to-date JSON Schema validation library in npm. You can use it in the handlers of action invokes or property writes in order to validate the data sent by the Consumer. In order to use ajv, we include it in line 19 and instantiate in line 20. How it can be used is seen in line 182 where an invalid data is responded with “Invalid input” error. +* WoTDevice class: WoTDevice gets the WoT object from the servient and TD Directory address for its constructor. It has attributes thing, deviceWoT and td. thing is instantiated as a result of the produce() method in lines 88-91. td is available from an ExposedThing using the getThingDescription() method. To avoid multiple calls to this method, we save it as the td attribute. deviceWoT attribute is assigned from the WoT argument passed in the constructor is used for instantiating everything. Once the constructor gets an ExposedThing, methods for initializing different interaction affordances are called, such as initializeProperties(). +* Thing Description: WoT.produce() takes as TD as argument and returns an ExposedThing. In this script, we use a TD with 1 property, 1 action and 1 event in order to demonstrate scripting for all interaction affordances. They are all named myX with X being an Interaction Affordance like property, action or event. +* Property Declarations (line 77): Here we add all needed properties as class members. Because we have one property "myProperty", we add a corresponding private member myProperty +* initializeProperties() method (line 164): This method exists in order to cleanly separate where the property handlers are created versus where they are assigned to properties. In this method, we define the properties of the WotDevice as class members, set their initial values and assign their corresponding read and write handlers. +* In line 166, we assign private class member myProperty the initial value "". + * In line 167, we set the corresponding readPropertyHandler by assigning the corresponding myPropertyReadHandler, defined in line 124, as its callback. +* If the property is writable, we similarly call the method setPropertyWriteHandler and assign the myPropertyWriteHandler method as its callback +* initilizeActions() method (line 171): This method exists in order to cleanly separate where the action handlers are created versus where they are assigned to actions. For an action with input data, the input validation would also happen here. By assigning to invoke handler to this.myActionHandler, we call a specific action invoke handler that can be easily encapsulated, allowing easy reusability. +* Line 95: We do not call add an initialization method for events, because events do not need handlers and can be emitted from anywhere (see myActionHandler method for an example) +* myPropertyReadHandler() (line 124): This is read-handler that can be called from any setPropertyReadHandler. The logic of reading, like reading a GPIO pin, should happen here. The value of the property will be then returned in return this.myProperty. Use of async-await allows easier programming of asynchronous operations happening inside a property handler. +* myPropertyWriteHandler() (line 129): This is write-handler that can be called from any setPropertyWriteHandler. The logic of writing, like assigning the input data to the corresponding variable, should happen here. This is where you also should call the emitPropertyChange method to signal that there is a change to your property if needed. Use of async-await allows easier programming of asynchronous operations happening inside a property handler. +* myActionHandler() (line 134): This is action invoke handler that can be called from any setActionHandler. The logic of the action handling, like rotating a robot arm, should happen here. The result of the action will be then returned in return outputData. Note that there should be no outputData returned if the action has no output member. Also, we demonstrate how to emit an event in line 148. Use of async-await allows easier programming of asynchronous operations happening inside an action handler. + +## What to change and get running + +If you don’t need to understand everything in the code, just make sure you do the following at least before installing, building and running: + +* package.json: + * Change package.json to include the bindings you want, e.g. add "@node-wot/binding-coap": "0.8.0", to dependencies. + * Change npm related information such as name, version etc. +* index.js: + * Add the required bindings in index.js in 3 locations: + * CoapServer = require("@node-wot/binding-coap").CoapServer (line 15) + + * servient.addServer(coapServer); (line 28) + * Change or remove the TD_DIRECTORY value in index.js (line 9) +* base.ts: +* Change the TD passed to this.WoT.produce() method in line 28 +* Add member variables that will act as properties, like in line 78 +* Write a property-read-handler for different properties, like in line 124 +* Write a property-write-handler for different properties, like in line 131 +* Write an action-invoke-handler for different actions, like in line 144 +* Decide when to emit events and adapt listenToMyEvent() in line 162 if needed +* Adapt initializeProperties of line 171: + * Assign the starting value for each property + * Set the Read Property handler for each property by adapting line 125 for you property. +* Adapt initializeActions() of line 178: + * set an Action Handler for each action you have, like in lines 180-190. You can use ajv for input validation. + +If you don’t need to understand everything in the code, just make sure you do the following at least before installing, building and running: + +* package.json: + * Change package.json to include the bindings you want, e.g. add "@node-wot/binding-coap": "0.8.0", to dependencies. + * Change npm related information such as name, version etc. +* index.js: + * Add the required bindings in index.js in 3 locations: + * CoapServer = require("@node-wot/binding-coap").CoapServer (line 15) + + * servient.addServer(coapServer); (line 28) + * Change or remove the TD_DIRECTORY value in index.js (line 9) +* base.ts: +* Change the TD passed to this.WoT.produce() method in line 28 +* Add member variables that will act as properties, like in line 78 +* Write a property-read-handler for different properties, like in line 124 +* Write a property-write-handler for different properties, like in line 131 +* Write an action-invoke-handler for different actions, like in line 144 +* Decide when to emit events and adapt listenToMyEvent() in line 162 if needed +* Adapt initializeProperties of line 171: + * Assign the starting value for each property + * Set the Read Property handler for each property by adapting line 125 for you property. +* Adapt initializeActions() of line 178: + * set an Action Handler for each action you have, like in lines 180-190. You can use ajv for input validation. + +## Installation and Running + +* Get the latest node.js: + +```bash +# Using Ubuntu +curl -fsSL https://deb.nodesource.com/setup_17.x | sudo -E bash - +sudo apt-get install -y nodejs +``` + +You will need to change 10.x to a newer version if needed + +* To install dependencies: npm install +* To build (transcompiling Typescript to JavaScript): npm run build +* To run the code: npm run start + +### Change from Version 0.7.X to 0.8.X for Exposed Things + +Version 0.8.X handles properties and interaction inputs differently than previous versions. Below is the list of changes: + +* Properties are not handled internally by node-wot anymore. Property handlers need to read and write to variables or class members that are explicitly defined in the code for the Exposed Things +* The value of interaction inputs cannot be accessed directly. WoT.InteractionInput objects have a member function value() that returns a promise that will resolve to the value of the input when available. You can either use input.value().then(...) or await input.value() in an async function. + +### Change from Version 0.6.X to 0.7.X for Exposed Things + +Resulting from the discussions in the Scripting API, the API has changed on 28.10.2019. This was a rather big change that also resulted changes in node-wot. Below is a list of changes: + +* You need to pass a full TD (but without forms) as argument to the produce() method. Before only non interaction information were passed. +* You cannot do myExposedThing.td and have to pass through myExposedThing.getThingDescription() +* WoTFactory is replaced by WoT in wot-typescript-definitions. You thus see WoT.produce() instead of thingFactory.produce() +* Since you pass a whole TD to produce() method, you don’t need addProperty, addAction and addEvent. +* Instead of this.thing.events[myEvent].emit(myPayload); there is this.thing.emitEvent(myEvent,myPayload); +* You have to use setActionHandler whereas before you could assign the handler in the addAction like addAction(name,metadata,handler). +* Since you cannot pass the initial value for a property with addProperty, you have to do a writeProperty(myInitialValue) at some point. +* You cannot change the TD of an ExposedThing, i.e. you cannot do thing.id="thingweb:io:example". + +You can see a git diff [here](https://github.com/tum-esi/wot-sys/commit/6cef8530b3317d98c2a7dea389c92ba2786be892#diff-0d33955cb472f41f07397fc2687c6425R10) diff --git a/hands-on/articles/intro-raspberry.md b/hands-on/articles/intro-raspberry.md new file mode 100644 index 0000000..c061852 --- /dev/null +++ b/hands-on/articles/intro-raspberry.md @@ -0,0 +1,258 @@ +--- +sidebar_position: 1 +title: Raspberry Pi Setup +description: This document aims to introduce the Web of Things (WoT) as building blocks for applications based on the IoT devices. +--- +# WoT - Introduction & Raspberry Pi Setup + +This document aims to introduce the Web of Things (WoT) as building blocks for applications based on the IoT devices. As a growing area, IoT services and application have a huge potential. From home automation to smart-grid passing by industrial manufacturers, IoT is gaining popularity as a potential solution to address their need. Several technologies can be used to build an IoT application mainly because of the specific constraints of the devices. This creates interoperability challenges for communication between devices. WoT offers an approach to expose and consume IoT resources as web resources. + +WoT is an initiative by the W3C to apply on the IoT device the same principles as for the existing web resources across the Internet. The main idea behind WoT is exposing virtual or physical devices as a resource with a description of its capabilities. That resource can then be accessed from a browser or another device in the same manner as a web page. WoT is not a proposition for a new communication protocol between devices, it uses existing protocols to communicate with the devices according to their communication capabilities. It presents a set of architectural and programming patterns for building interoperable devices based on the following three fundamentals: + +* Uniform Resource Identifier (URI) for identifying devices and their descriptions +* A wide variety of existing protocols for accessing the devices +* A description of the description as metadata used both for interoperability and presentability purposes + +## WoT Architecture + +The central component of the WoT architecture is “WoT Servient” which is functional virtual device. A Servient extends the IoT physical devices by providing standard access and control capabilities to the devices. + +A Servient provides a protocol agnostic runtime for the application using the resource model. Servient application uses this resource model which enables interoperability with other Servients and users that are using multiple bindings. Servient may act at the same time as a client and a server according to the applications' behavior. The resources associated to a Servient instance are described in a Thing description. It uses JSON-LD to make this description readable by both humans and machines. Such a description enhances the machine to machine communication and makes the Things ready for the Semantic Web. + +A Servient instance can run on multiple platforms at different layer of the IoT network. It can be deployed inside the IoT device itself in condition to have a minimum processing power. It may also be deployed inside a smart hub or edge node to adapt legacy devices to the architecture. This adaptation role can also be provided by a Servient deployed on the cloud. Last but not least, Servient instances can be accessed as web resources by a smartphone and web browsers. + +# Setup the Raspberry Pi Zero W + +We assume that the Raspberry Pi used is a freshly installed one with Debian. First, it needs to be configured for a network connection. Second, the environment needs to be configured mainly by installing Node.js and a few other dependencies. Finally, things-web needs to be installed on the system. + +## Network configuration + +Insert the SD card into your card reader and create the two following files as illustrated in the image below: + +wpa_supplicant.conf: is the file that is used to configure your WiFi on the command line. This file must contain the following configuration where ###### is your WiFi password: + +```bash +country=US +ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev +update_config=1 +network={ + ssid="IoT-testbed-2.4" + psk="#########" + key_mgmt=WPA-PSK + proto=RSN + pairwise=CCMP + group=CCMP + auth_alg=OPEN +} +``` + +## Installing Node.js + +Ideally, Node.js 10 should be installed. It works also with Node.js 8 but Node.js 10 is highly recommended. To install the Node.js version 10, make sure that the right architecture is used. Below the commands for the Raspberry Pi Zero W: + +```bash +wot@node-wot:~$ wget https://nodejs.org/dist/v10.15.0/node-v10.15.0-linux-armv6l.tar.xz +wot@node-wot:~$ sudo mkdir /usr/local/lib/nodejs +wot@node-wot:~$ sudo tar -xJvf node-v10.15.0-linux-armv6l.tar.xz -C /usr/local/lib/nodejs +wot@node-wot:~$ sudo mv /usr/local/lib/nodejs/node-v10.15.0-linux-armv6l /usr/local/lib/nodejs/node-v10.15.0 +wot@node-wot:~$ nano ~/.profile +``` + +Inside the ~/.profile, add the following: + +```bash +export NODEJS_HOME=/usr/local/lib/nodejs/node-v10.15.0/bin +export PATH=$NODEJS_HOME:$PATH +``` + +```bash +wot@node-wot:~$ . ~/.profile +wot@node-wot:~$ node -v +wot@node-wot:~$ npm version +``` + +## Cloning the repository + +The reference implementation of the Web of Things is published in GitHub as node-wot project at GitHub. The project is part of the Eclipse Foundation. Use the command below to clone the repository on your local system: + +```bash +wot@node-wot:~$ sudo apt install git +wot@node-wot:~$ git clone https://github.com/eclipse-thingweb/node-wot +``` + +## Installation + +The installation process is composed of mainly two steps. The first step installs the Node.js dependences. The second step installs and builds the node-wot project. + +### Installing the packages +Node-wot requires dependencies such as Typescript, lerna, etc. By running the command below, those dependencies are installed: + +```bash +wot@node-wot:~$ cd node-wot +wot@node-wot:~$ npm install +``` + +### Building the libraries + +As the node-wot project is mainly developed using Typescript, tsc command needs to be executed to trans-compile that code to JavaScript. The command below builds the project and its packages: + +```bash +wot@node-wot:~$ npm run build +``` + +### Running the example Servient + +Run the command below to expose a “server” Servient: + +```bash +wot@node-wot:~$ node packages/cli/dist/cli.js examples/scripts/counter.js +``` + +You can access the Thing Description generated at http://localhost:8080/counter. + +## Thing Description + +The Thing Description (TD) is one major element of the web of Things approach. It is a JSON or JSON-LD object that describes a Thing. As illustrated below, it describes aspects such as name, description, list of accessible properties and list of available actions. + +### Properties + +The property section describes interesting information about the exposed property as illustrated below. It offers also the “href” that defines the URI that the client can use to access this property as a resource. + +### Actions + +The actions section describe the actions exposed by the Thing. They enable a client to remotely invoke the function associated to this action. Like for the properties, the actions expose an “href” URI that can be used to invoke those actions as illustrated below: + +### Standard description + +The full list of the elements that can be used in a TD is available in the W3C document at https://www.w3.org/TR/wot-thing-description/. + +Once you create a Servient using the reference implementation, a TD respecting the standard is automatically generated for your exposed Thing. The next section describes how to create a Servient and access its TD. + +## A Servient + +Web of Things programming model is based on the notion of “Servient”. A Servient is a program developed using the WoT Scripting API and can behave at the same time as a server and a client. For example, a Servient can be a client for a field device (light bulb) and server for the mobile application that is used to control that device. + +### Servient’s structure + +As previously stated, a Servient can be both a client and a server. The structure of a Servient varies depending on the target behavior. However, it is centered on the Thing Description. To expose a new Thing (server mode), you need first to create the Thing by passing some metadata to the Scripting API as illustrated below: + +```js +WoT.produce({ + title: "counter", + description: "counter example Thing", + "@context": "https://www.w3.org/2019/wot/td/v1", + properties: { + count: { + type: "integer", + description: "current counter value", + observable: true, + readOnly: true, + } + }, + actions: { + increment: { + description: "Incrementing counter value", + uriVariables: { + step: { type: "integer", minimum: 1, maximum: 250 }, + }, + } + } +}) + .then((thing) => { + console.log("Produced " + thing.getThingDescription().title); + + // init property values + // ... + // set property handlers + // ... + // set action handlers + // ... + + // expose the thing + thing.expose().then(() => { + console.info(thing.getThingDescription().title + " ready"); + }); + }) + .catch((e) => { + console.log(e); + }); +``` + +This code initiates the creation of a Thing named “counter” with its interactions and adds metadata such as context to that Thing. + +This will create the property, so it can be exposed and accessed both using the Scripting API and using a binding (by default, the HTTP, and CoAP bindings are used to expose Things on node-wot). + +Once your run the Servient, the exposed property will be accessible at http://localhost:8080/counter/properties/count as illustrated below: + +Before we expose properties/actions/events, we need to add handlers (e.g., an action handler is added as described below). + +```js +thing.setActionHandler("increment", async (params, options) => { + let step = 1; + if (options && typeof options === "object" && "uriVariables" in options) { + if ("step" in options.uriVariables) { + const uriVariables = options.uriVariables as RecordThing
+Thing
+TD
+TM
+Domus TDD
+TD Tools
+Playground
+node-wot
+dart_wot
+Node-RED
+Discord Members
+GitHub Contributors
+Adopters
+Do you like our new website?
+Leave us some feedback!
+Leverage web standards for faster development and better interoperability.
+Thing
+Thing
+TD
+TM
+node-wot
+dart_wot
+Node-RED
+Browser
+Mobile
+Mobile
+{description}
+{tag}
+ ) +} + + +export default function ServicesSection() { + return ( +Thingweb also provides you with a variety of publicly available Things for you to interact with over the internet.
+ +Thingweb has the components you need to interact with your devices, tools to design Thing Descriptions and services to manage your devices. Pick what you need, use as you see fit.
+ + +A fast and extensible framework to connect any device with your browser and backend applications.
+VS Code extension for validating and designing W3C Thing Descriptions and Thing Models.
+Framework to build Web of Things applications in Dart and Flutter.
+WoT Application Manager - a CLI to quickly build a Web of Things application.
+Browser application for validating and designing W3C Thing Descriptions and Thing Models.
+Semantic storage for device metadata based on W3C Thing Description information model.
+Utility libraries for W3C Thing Descriptions and Thing Models.
+Develop interoperable IoT applications + with intuitive tools and leveraging well know web standards.
+ +Build IoT applications with secure, scalable web capabilities, flexible protocols, device fleet management, and documentation.
+Eliminate compatibility headaches by leveraging Web standards to ensure your applications remain compatible and adaptable.
+Join our open community! Everyone has the power to contribute and make a meaningful impact on the future of Thingweb.
+Start small and get an off-the-shelf IoT device.
+Integrate Thingweb components into your IoT application and be open to scale.
+Easily manage a fleet of heterogeneous devices and orchestrate applications at scale.
+- Eclipse Thingweb™ offers components for making IoT solutions interoperable at scale by - leveraging the W3C WoT - standards, no matter if improving an existing solution or building a new one: -
- -- Each component within the Eclipse Thingweb™ project is designed to be used independently - from each other while working - harmoniously together. - This gives developers the flexibility to choose the specific tools they need for their IoT - solution without sacrificing interoperability. -
- -
- The Eclipse Thingweb™ node-wot
is the official reference implementation of
- the Web of Things (WoT) Scripting API written in the official
- specification.
-
-
node-wot
provides a WoT Thing Description parser and serializer, several "Protocol
- Bindings" implementing the WoT Binding Templates, as well as a runtime system ("WoT
- Runtime") providing the WoT Scripting API for applications. It is based on Node.js
- runtime and developed under open-source licenses on GitHub.
-
- node-wot
also provides a browser bundle to visualize TDs and to enable the
- interaction with Things from the Web browser. A simple example can be found here: WebUI.
-
- It is not only a toolkit with some demo applications. node-wot
- enables you to create and experiment with real-world WoT applications.
-
- Eclipse Thingweb™ Playground is a set of software packages that allow to validate and - manipulate Thing Descriptions. All individual packages can be used as a Node.js - dependency but also via a CLI or Web interface.
-- You can explore it on the Web interface or at the GitHub - repository. - You can transform TDs into Open API, Async API or AAS Asset Interface Description and - explore different features of the Thing Description specification via our examples. -
-Itaque earum rerum hic tenetura sapiente delectus,
-Itaque earum rerum hic tenetura sapiente delectus,
-Itaque earum rerum hic tenetura sapiente delectus,
-Itaque earum rerum hic tenetura sapiente delectus,
-In ullamcorper est eget tempor cursus neque mi consectetuer mi a ultricies massa est sed nisl Class aptent taciti sociosqu ad litora torquent per conubia nostra
-In ullamcorper est eget tempor cursus neque mi consectetuer mi a ultricies massa est sed nisl Class aptent taciti sociosqu ad litora torquent per conubia nostra
-In ullamcorper est eget tempor cursus neque mi consectetuer mi a ultricies massa est sed nisl Class aptent taciti sociosqu ad litora torquent per conubia nostra
-t |