Skip to content

Commit 06a53a3

Browse files
docs: align with the current form/code-style and counter example (#1386)
* docs: align with the current form/code-style and counter example * docs: add prerequisites
1 parent 084cef4 commit 06a53a3

File tree

1 file changed

+111
-74
lines changed

1 file changed

+111
-74
lines changed

API.md

Lines changed: 111 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,35 @@ These can be combined into a Thing that interacts with other Things.
88
Creating a WoT Thing is called exposing a Thing.
99
Exposing a Thing creates a Thing Description that can be used to by others to interact with this Thing.
1010

11+
##### Prerequisites
12+
13+
- `npm install @node-wot/core`
14+
- `npm install @node-wot/binding-http`
15+
- `npm install @node-wot/binding-coap`
16+
- ...
17+
1118
##### Starting a Servient
1219

1320
```javascript
14-
WotCore = require("@node-wot/core");
15-
let servient = new WotCore.Servient();
16-
let WoT = await servient.start();
21+
const { Servient } = require("@node-wot/core");
22+
const servient = new Servient();
23+
servient.start().then(async (WoT) => {
24+
// ...
25+
});
1726
```
1827

1928
##### In Client mode, add factories
2029

2130
```javascript
22-
WotCore = require("@node-wot/core");
23-
BindingHttp = require("@node-wot/binding-http");
24-
BindingCoap = require("@node-wot/binding-coap");
25-
let servient = new NodeWoTCore.Servient();
26-
servient.addClientFactory(new BindingHttp.HttpClientFactory());
27-
servient.addClientFactory(new BindingCoap.CoapClientFactory());
31+
const { Servient } = require("@node-wot/core");
32+
const { HttpClientFactory } = require("@node-wot/binding-http");
33+
const { CoapClientFactory } = require("@node-wot/binding-coap");
34+
const servient = new Servient();
35+
servient.addClientFactory(new HttpClientFactory());
36+
servient.addClientFactory(new CoapClientFactory());
37+
servient.start().then(async (WoT) => {
38+
// ...
39+
});
2840
```
2941

3042
The different bindings offer client factories.
@@ -35,24 +47,28 @@ For more details on bindings, e.g. configuration options for a specific `*Client
3547
##### In Server mode, add servers
3648

3749
```javascript
38-
WotCore = require("@node-wot/core");
39-
CoapServer = require("@node-wot/binding-coap").CoapServer;
40-
let servient = new WotCore.Servient();
41-
servient.addServer(new CoapServer());
50+
const { Servient } = require("@node-wot/core");
51+
const { HttpServer } = require("@node-wot/binding-http");
52+
const servient = new Servient();
53+
servient.addServer(new HttpServer({}));
54+
servient.start().then(async (WoT) => {
55+
// ...
56+
});
4257
```
4358

4459
Same as for clients, bindings offer servers.
4560

4661
##### Credentials
4762

4863
```javascript
49-
let servient = new (require("@node-wot/core")).Servient();
64+
const { Servient } = require("@node-wot/core");
65+
const servient = new Servient();
5066
servient.addCredentials({
5167
"urn:dev:ops:32473-example-thing": {
52-
"username": "admin",
53-
"password:" "password" // if you copy these and don't change them, don't claim you were "hacked"
54-
}
55-
);
68+
username: "admin",
69+
password: "password", // if you copy these and don't change them, don't claim you were "hacked"
70+
},
71+
});
5672
```
5773

5874
You can add credentials like this.
@@ -64,17 +80,22 @@ Authentication data is always mapped to a Thing through its id.
6480
##### Expose a Thing
6581

6682
```javascript
67-
let thing = WoT.produce({
83+
WoT.produce({
6884
title: "counter",
69-
description: "counter example Thing",
70-
});
85+
description: "counter example thing",
86+
}).then((thing) => {
87+
console.log(thing.getThingDescription().title + " produced");
7188

72-
// any other code to develop the Thing
89+
// any other code to develop the thing
7390

74-
thing.expose();
91+
// expose the thing
92+
thing.expose().then(() => {
93+
console.info(thing.getThingDescription().title + " exposed");
94+
});
95+
});
7596
```
7697

77-
Here, an object named `thing` is produced. At this stage, it has only a name and a description for humans to read.
98+
Here, an object named `thing` is produced. At this stage, it has only a title and a description for humans to read.
7899
`thing.expose();` exposes/starts the exposed Thing in order to process external requests. This also creates a Thing Description that describes the interfaces of the `counter` thing.
79100

80101
##### Add a Property definition to the Thing
@@ -85,20 +106,22 @@ They are added as part of the `WoT.produce` invocation, like so:
85106

86107
```javascript
87108
WoT.produce({
88-
title: "property",
109+
title: "counter",
110+
description: "counter example thing",
89111
properties: {
90-
counter: {
112+
count: {
91113
type: "integer",
92114
description: "current counter value",
93-
observable: false,
94115
},
95116
},
117+
}).then((thing) => {
118+
// thing.setPropertyReadHandler(...);
119+
// thing.setPropertyWriteHandler(...);
120+
// thing.expose().then(() => { ...});
96121
});
97122
```
98123

99-
This creates a Property.
100-
Its value can be initializes by calling `writeProperty`, otherwise it reads as `null`.
101-
After being written to, the value can be read by other Things.
124+
This creates a property `count`.
102125

103126
You can create a Property that has a more complex type, such as an object. This is shown in the following:
104127

@@ -121,73 +144,87 @@ WoT.produce({
121144
##### Add a Property read handler
122145

123146
```javascript
124-
thing.setPropertyReadHandler("counter", (propertyName) => {
125-
console.log("Handling read request for " + propertyName);
126-
return new Promise((resolve, reject) => {
127-
resolve(Math.random(100));
147+
let count = 0;
148+
servient.start().then(async (WoT) => {
149+
WoT.produce({
150+
title: "counter",
151+
description: "counter example thing",
152+
properties: {
153+
count: {
154+
type: "integer",
155+
},
156+
},
157+
}).then((thing) => {
158+
thing.setPropertyReadHandler("count", async () => count);
159+
// expose the thing
160+
thing.expose().then(() => {
161+
// ...
162+
});
128163
});
129164
});
130165
```
131166

132-
You can specify if the Thing needs to do something in case of a property read.
133-
Here, instead of reading a static value, a new random value is generated on every invocation.
167+
You can specify if the thing needs to do something in case of a property read.
168+
Here, a value is reported.
134169

135170
##### Add a Property write handler
136171

137172
```javascript
138-
thing.setPropertyWriteHandler("brightness", (value) => {
139-
return new Promise((resolve, reject) => {
140-
value %= 2; // only even values are valid in this example
141-
setBrightness(value);
142-
resolve(value);
173+
let count = 0;
174+
servient.start().then(async (WoT) => {
175+
WoT.produce({
176+
title: "counter",
177+
description: "counter example thing",
178+
properties: {
179+
count: {
180+
type: "integer",
181+
},
182+
},
183+
}).then((thing) => {
184+
thing.setPropertyWriteHandler("count", async (intOutput, options) => {
185+
count = await intOutput.value();
186+
return undefined;
187+
});
188+
// ...
143189
});
144190
});
145191
```
146192

147-
You can specify if the Thing needs do to something in case of a property write.
148-
Here, the value written is used to set the brightness of an LED that requires a specific function (`setBrightness()`) to do that.
149-
The property value becomes the value passed to `resolve()`, which in this case would mean the number modulo 2.
193+
You can specify if the thing needs do to something in case of a property write.
194+
Here, the value is used to set the `count` value.
150195

151196
##### Add an Action definition to the Thing
152197

153-
Actions offer functions of the Thing.
154-
These functions may manipulate the interal state of a Thing in a way that is not possible through setting Properties.
155-
Examples are changing internal state that is not exposed as a Property, changing multiple Properties, changing Properties over time or with a process that shall not be disclosed.
198+
Actions offer functions of the thing.
199+
These functions may manipulate the interal state of a thing in a way that is not possible through setting properties.
200+
Examples are changing internal state that is not exposed as a property, changing multiple properties, changing properties over time or with a process that shall not be disclosed.
156201
Actions may also be pure functions, that is, they do not use any internal state at all, e.g. for processing input data and returning the result directly.
157202

158-
Just like Properties above, adding Actions is done as part of a WoT.produce() call.
203+
Just like properties above, adding actions is done as part of a WoT.produce() call.
159204

160205
```javascript
161206
WoT.produce({
162-
title: "action",
163-
actions: {
164-
echo: {
165-
description: "Returns what it gets passed. Subject to SLA. Will probably terminate at null-bytes, because it treats input as strings."
166-
input: { type: "string" },
167-
output: { type: "string" }
168-
}
169-
}
170-
})
207+
title: "counter",
208+
actions: {
209+
increment: {
210+
title: "increment",
211+
},
212+
},
213+
});
171214
```
172215

173-
As can be seen above, `input` and `output` data types can be specified, similar to how property types are described in TDs.
216+
Note: `input` and `output` data types can be specified, similar to how property types are described in TDs.
174217

175-
##### Add an Action invoke handler
218+
##### Add an Action handler
176219

177-
You need to write what will happen if an Action is invoked. This is done by setting an Action Handler:
220+
You need to code what will happen if an action is invoked. This is done by setting an action handler:
178221

179222
```javascript
180223
thing.setActionHandler("increment", () => {
181-
console.log("Incrementing");
182-
return thing.readProperty("counter").then((count) => {
183-
let value = count + 1;
184-
thing.writeProperty("counter", value);
185-
});
224+
count = count + 1;
186225
});
187226
```
188227

189-
Here, you see also how to access the properties of a Thing you are creating.
190-
191228
##### Add an Event definition to the Thing
192229

193230
The Event Interaction Affordance describes event sources that asynchronously push messages.
@@ -213,8 +250,8 @@ WoT.produce({
213250

214251
```javascript
215252
setInterval(async () => {
216-
++counter;
217-
thing.emitEvent("onchange", counter);
253+
++count;
254+
thing.emitEvent("onchange", count);
218255
}, 5000);
219256
```
220257

@@ -256,12 +293,12 @@ URLs can have various schemes, including `file://` to read from the local filesy
256293

257294
```javascript
258295
WoT.requestThingDescription("http://localhost:8080/counter").then(async (td) => {
259-
let thing = WoT.consume(td);
296+
const thing = await WoT.consume(td);
260297
// Do something with the consumed Thing
261298
});
262299
```
263300

264-
Things can be `consume`d no matter if they were fetched with `WoT.requestThingDescription()`, `WoTHelpers.fetch()` or any other mean.
301+
Things can be `consume`d no matter if they were fetched with `WoT.requestThingDescription()` or any other mean.
265302
`consume` only requires a TD as an `Object`, so you could also use `fs.readFile` and `JSON.parse` or inline it into your code.
266303
As long at it results in a TD Object, you can receive it over Fax, Morse it or use smoke signals.
267304

@@ -277,8 +314,8 @@ So you should handle it explicitely.
277314
Here we use the await functionality of Node.js.
278315

279316
```javascript
280-
let read1 = await thing.readProperty("count");
281-
let value = await read1.value();
317+
let read = await thing.readProperty("count");
318+
let value = await read.value();
282319
console.info("count value is", value);
283320
```
284321

@@ -287,7 +324,7 @@ console.info("count value is", value);
287324
You can write to a property by using the `writeProperty` function.
288325

289326
```javascript
290-
thing.writeProperty("color", { r: 255, g: 255, b: 0 });
327+
await thing.writeProperty("color", { r: 255, g: 255, b: 0 });
291328
```
292329

293330
<!-- * Observe value changes of a Property. -->

0 commit comments

Comments
 (0)