/********************************************************************************
 * Copyright (c) 2019 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 * as WoT from "wot-typescript-definitions" ; var request = require ( "request" ) ; const Ajv = require ( "ajv" ) ; var ajv = new Ajv ( ) ; export class WotDevice { public thing : WoT . ExposedThing ; public deviceWoT : typeof WoT ; public td : WoT . ThingDescription ; private thingModel : WoT . ThingDescription = { "@context" : [ "https://www.w3.org/2019/wot/td/v1" , { "@language" : "en" } ] , "@type" : "" , id : "new:thing" , title : "" , description : "" , securityDefinitions : { "" : { scheme : "" , } , } , security : "" , properties : { myProperty : { title : "A short title for User Interfaces" , description : "A longer string for humans to read and understand" , unit : "" , type : "" , } , } , actions : { myAction : { title : "A short title for User Interfaces" , description : "A longer string for humans to read and understand" , input : { unit : "" , type : "number" , } , out : { unit : "" , type : "string" , } , } , } , events : { myEvent : { title : "A short title for User Interfaces" , description : "A longer string for humans to read and understand" , data : { unit : "" , type : "" , } , } , } , } ; private tdDirectory : string ; private myProperty : WoT . InteractionInput ; constructor ( deviceWoT , tdDirectory ? ) { this . deviceWoT = deviceWoT ; if ( tdDirectory ) this . tdDirectory = tdDirectory ; } public async startDevice ( ) { console . log ( `Producing Thing: ${ this . thingModel . title }` ) ; const exposedThing = await this . deviceWoT . produce ( this . thingModel ) ; console . log ( "Thing produced" ) ; this . thing = exposedThing ; this . td = exposedThing . getThingDescription ( ) ; this . initializeProperties ( ) ; this . initializeActions ( ) ; console . log ( `Exposing Thing: ${ this . thingModel . title }` ) ; await this . thing . expose ( ) ; console . log ( "Exposed Thing" ) ; if ( this . tdDirectory ) { this . register ( this . tdDirectory ) ; } this . listenToMyEvent ( ) ; } public register ( directory ) { console . log ( "Registering TD in directory: " + directory ) ; request . post ( directory , { json : this . thing . getThingDescription ( ) } , ( error , response , body ) => { if ( ! error && response . statusCode < 300 ) { console . log ( "TD registered!" ) ; } else { console . debug ( error ) ; console . debug ( response ) ; console . warn ( "Failed to register TD. Will try again in 10 Seconds..." ) ; setTimeout ( ( ) => { this . register ( directory ) ; } , 10000 ) ; return ; } } ) ; } private myPropertyReadHandler ( ) { return new Promise < WoT . InteractionInput > ( ( resolve , reject ) => { resolve ( this . myProperty ) ; } ) ; } private myPropertyWriteHandler ( inputData , options ? ) { return new Promise < void > ( ( resolve , reject ) => { this . myProperty = inputData ; resolve ( ) ; } ) ; } private myActionHandler ( inputData ? , options ? ) { return new Promise < WoT . InteractionInput > ( ( resolve , reject ) => { if ( inputData ) { this . thing . emitEvent ( "myEvent" , null ) ; } let outputData = "" ; if ( outputData ) { resolve ( outputData ) ; } else { resolve ( null ) ; } } ) ; } private listenToMyEvent ( ) { } private initializeProperties ( ) { this . myProperty = "" ; this . thing . setPropertyReadHandler ( "myProperty" , this . myPropertyReadHandler ) ; this . thing . setPropertyWriteHandler ( "myProperty" , this . myPropertyWriteHandler ) ; } private initializeActions ( ) { this . thing . setActionHandler ( "myAction" , ( inputData ) => { return new Promise ( ( resolve , reject ) => { if ( ! ajv . validate ( this . td . actions . myAction . input , inputData ) ) { reject ( new Error ( "Invalid input" ) ) ; } else { resolve ( this . myActionHandler ( inputData ) ) ; } } ) ; } ) ; } }