Skip to content

Instantly share code, notes, and snippets.

@danielpeintner
Created April 28, 2022 08:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danielpeintner/ed6d6d0c6a1e511d81a4571be48d35b8 to your computer and use it in GitHub Desktop.
Save danielpeintner/ed6d6d0c6a1e511d81a4571be48d35b8 to your computer and use it in GitHub Desktop.
/********************************************************************************
* Copyright (c) 2022 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and
* Document License (2015-05-13) which is available at
* https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document.
*
* SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
********************************************************************************/
import { Servient } from "@node-wot/core";
import { HttpClientFactory } from "@node-wot/binding-http";
import { ThingDescription } from "wot-typescript-definitions";
// create Servient and add HTTP binding
const servient = new Servient();
servient.addClientFactory(new HttpClientFactory());
servient.addCredentials({ "urn:projects.wot.ditto:lamp/features/status": { username: "other", password: "other" }});
// copy of "http://raw.githubusercontent.com/aleshark87/WoTModels/main/lamp/status.td.jsonld"
const td : ThingDescription = {
"@context":[
"https://www.w3.org/2022/wot/td/v1.1"
],
"title":"Status",
"@type":"Thing",
"id":"urn:projects.wot.ditto:lamp/features/status",
"base":"http://localhost:8080/api/2/things/projects.wot.ditto:lamp/features/status",
"version":{
"model":"1.0.0",
"instance":"1.0.0"
},
"links":[
{
"rel":"collection",
"href":"http://localhost:8080/api/2/things/projects.wot.ditto:lamp",
"type":"application/td+json"
},
{
"rel":"type",
"href":"https://raw.githubusercontent.com/aleshark87/WoTModels/main/lamp/status.jsonld",
"type":"application/tm+json"
}
],
"security":"basic_sc",
"securityDefinitions":{
"basic_sc":{
"in":"header",
"scheme":"basic"
}
},
"support":"https://www.eclipse.org/ditto/",
"created":"2022-04-08T15:42:19.846756539Z",
"forms":[
{
"op":"readallproperties",
"href":"/properties{?channel,timeout}",
"htv:methodName":"GET",
"contentType":"application/json",
"additionalResponses":[
{
"success":false,
"schema":"dittoError"
}
]
},
{
"op":"readmultipleproperties",
"href":"/properties{?fields,channel,timeout}",
"htv:methodName":"GET",
"contentType":"application/json",
"additionalResponses":[
{
"success":false,
"schema":"dittoError"
}
]
},
{
"op":"writeallproperties",
"href":"/properties{?channel,timeout,response-required}",
"htv:methodName":"PUT",
"contentType":"application/json",
"additionalResponses":[
{
"success":false,
"schema":"dittoError"
}
]
},
{
"op":"writemultipleproperties",
"href":"/properties{?channel,timeout,response-required}",
"htv:methodName":"PATCH",
"contentType":"application/merge-patch+json",
"additionalResponses":[
{
"success":false,
"schema":"dittoError"
}
]
},
{
"op":[
"observeallproperties",
"unobserveallproperties"
],
"href":"/properties",
"htv:methodName":"GET",
"subprotocol":"sse",
"contentType":"text/event-stream",
"additionalResponses":[
{
"success":false,
"schema":"dittoError"
}
]
},
{
"op":[
"subscribeallevents",
"unsubscribeallevents"
],
"href":"/outbox/messages",
"htv:methodName":"GET",
"subprotocol":"sse",
"contentType":"text/event-stream",
"additionalResponses":[
{
"success":false,
"schema":"dittoError"
}
]
}
],
"properties":{
"lamp-status":{
"title":"Lamp Status",
"description":"The current Lamp Status.",
"type":"boolean",
"default":false,
"observable":true,
"forms":[
{
"op":"readproperty",
"href":"/properties/lamp-status{?channel,timeout}",
"htv:methodName":"GET",
"contentType":"application/json",
"additionalResponses":[
{
"success":false,
"schema":"dittoError"
}
]
},
{
"op":"writeproperty",
"href":"/properties/lamp-status{?channel,timeout,response-required}",
"htv:methodName":"PUT",
"contentType":"application/json",
"additionalResponses":[
{
"success":false,
"schema":"dittoError"
}
]
},
{
"op":"writeproperty",
"href":"/properties/lamp-status{?channel,timeout,response-required}",
"htv:methodName":"PATCH",
"contentType":"application/merge-patch+json",
"additionalResponses":[
{
"success":false,
"schema":"dittoError"
}
]
},
{
"op":[
"observeproperty",
"unobserveproperty"
],
"href":"/properties/lamp-status",
"htv:methodName":"GET",
"subprotocol":"sse",
"contentType":"text/event-stream",
"additionalResponses":[
{
"success":false,
"schema":"dittoError"
}
]
}
]
}
},
"uriVariables":{
"channel":{
"type":"string",
"title":"The Ditto channel to interact with.",
"description":"Defines to which channel to route the command: 'twin' (digital twin) or 'live' (the device).",
"enum":[
"twin",
"live"
],
"default":"twin"
},
"timeout":{
"type":"integer",
"title":"The timeout to apply.",
"description":"Defines how long the backend should wait (in seconds) for completion of the request. A value of '0' applies fire and forget semantics for the command.",
"minimum":0,
"maximum":60,
"default":60
},
"response-required":{
"type":"boolean",
"title":"If a response is required.",
"description":"Defines whether a response is required to the API call or not.",
"default":true
},
"fields":{
"type":"string",
"title":"Fields to select.",
"description":"Contains a comma-separated list of fields (e.g. property names) to be included in the returned JSON."
}
},
"schemaDefinitions":{
"dittoError":{
"type":"object",
"title":"Ditto error.",
"description":"Provides additional information about an occurred error and how to resolve it.",
"properties":{
"description":{
"type":"string",
"title":"Error description.",
"description":"Contains further information about the error e.g. a hint what caused the problem and how to solve it."
},
"error":{
"type":"string",
"title":"Error code identifier.",
"description":"The error code or identifier that uniquely identifies the error."
},
"message":{
"type":"string",
"title":"Error message.",
"description":"The human readable message that explains what went wrong during the execution of a command/message."
},
"href":{
"type":"string",
"title":"Error link.",
"description":"A link to further information about the error and how to fix it.",
"format":"uri"
},
"status":{
"type":"integer",
"title":"Status code.",
"description":"The status code of the error with HTTP status code semantics (e.g.: 4xx for user errors, 5xx for server errors).",
"minimum":400,
"maximum":599
}
},
"required":[
"status",
"error",
"message"
]
}
}
} as ThingDescription;
async function main() {
try {
const WoT = await servient.start();
const thing = await WoT.consume(td);
// read property
const read1 = await thing.readProperty("lamp-status"); // { uriVariables: { channel: "twin", timeout: 60 } }
console.log("lamp-status value is: ", await read1.value());
} catch (err) {
console.error("Script error:", err);
}
}
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment