Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 33 additions & 27 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -636,9 +636,9 @@ <h2>The <dfn>ExposedThing</dfn> interface</h2>
ExposedThing addEvent(ThingEvent event);
ExposedThing removeEvent(DOMString name);
// define request handlers
ExposedThing setPropertyReadHandler(PropertyReadHandler readHandler, optional DOMString propertyName);
ExposedThing setPropertyWriteHandler(PropertyWriteHandler writeHandler, optional DOMString propertyName);
ExposedThing setActionHandler(ActionHandler action, optional DOMString actionName);
ExposedThing setPropertyReadHandler(DOMString name, PropertyReadHandler readHandler);
ExposedThing setPropertyWriteHandler(DOMString name, PropertyWriteHandler writeHandler);
ExposedThing setActionHandler(DOMString name, ActionHandler action);
};
callback PropertyReadHandler = Promise&lt;any&gt;();
callback PropertyWriteHandler = Promise&lt;void&gt;(any value);
Expand Down Expand Up @@ -786,14 +786,14 @@ <h4>The <dfn>ThingEvent</dfn> dictionary</h4>
<section data-dfn-for="PropertyReadHandler">
<h3>The <dfn>PropertyReadHandler</dfn> callback</h3>
<p>
A function called with a <code>propertyName</code> argument that returns a Promise and resolves it with the value of the <a>Property</a> matching <code>propertyName</code>, or rejects with and error if the property is not found or the value cannot be retrieved.
A function that returns a Promise and resolves it with the value of the <a>Property</a> matching the <code>name</code> argument to the <code>setPropertyReadHandler</code> function, or rejects with an error if the property is not found or the value cannot be retrieved.
</p>
</section>

<section data-dfn-for="PropertyWriteHandler">
<h3>The <dfn>PropertyWriteHandler</dfn> callback</h3>
<p>
A function called with a <code>propertyName</code> and a <code>value</code> argument that returns a Promise and resolves it when the value of the <a>Property</a> matching <code>propertyName</code> is updated with <code>value</code>, or rejects with and error if the property is not found or the value cannot be updated. The property is updated by the implementation with the value that is resolved by this callback.
A function called with <code>value</code> as argument that returns a Promise which is resolved when the value of the <a>Property</a> matching the <code>name</code> argument to the <code>setPropertyReadHandler</code> function is updated with <code>value</code>, or rejects with an error if the property is not found or the value cannot be updated.
</p>
<p class="ednote">
Note that this function is invoked by implementations before the property is updated, so the code in this callback function can invoke the <code>readProperty()</code> method to find out the old value of the property, if needed. Therefore the old value is not provided to this method.
Expand All @@ -803,37 +803,37 @@ <h3>The <dfn>PropertyWriteHandler</dfn> callback</h3>
<section data-dfn-for="ActionHandler">
<h3>The <dfn>ActionHandler</dfn> callback</h3>
<p>
A function called with any parameters that returns a Promise.
A function called with a <code>parameters</code> dictionary argument assembled by the <a>WoT runtime</a> based on the <a>Thing Description</a> and the external client request. It returns a Promise that rejects with an error or resolves if the action is successful or ongoing (may also resolve with a control object such as an <a>Observable</a> for actions that need progress notifications or that can be canceled).
</p>
</section>

<section> <h3>The <dfn>setPropertyReadHandler()</dfn> method</h3>
<p>
Takes a <code>propertyName</code> as an optional string argument, and a <code>readHandler</code> argument of type <a>PropertyReadHandler</a>. Sets the handler function for reading the specified <a>Property</a> matched by <code>propertyName</code> if <code>propertyName</code> is specified, otherwise sets it for reading any property. Throws on error. Returns a reference to the same object for supporting chaining.
Takes <code>name</code> as string argument and <code>readHandler</code> as argument of type <a>PropertyReadHandler</a>. Sets the handler function for reading the specified <a>Property</a> matched by <code>name</code>. Throws on error. Returns a reference to the same object for supporting chaining.
</p>
<p>
If provided, this callback function will implement reading a <a>Property</a> and SHOULD be called by implementations when a request for reading a <a>Property</a> is received from the underlying platform.
The <code>readHandler</code> callback function will implement reading a <a>Property</a> and SHOULD be called by implementations when a request for reading a <a>Property</a> is received from the underlying platform.
</p>
<p>
There SHOULD be at most one handler for any given <a>Property</a>. If no handler is initialized for any given <a>Property</a>, implementations SHOULD implement default property read without calling this hook.
There SHOULD be at most one handler for any given <a>Property</a> and newly added handlers replace the old handlers. If no handler is initialized for any given <a>Property</a>, implementations SHOULD implement a default property read handler.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor comment: in node-wot we deal with any property without a readHandler by simply returning the value as is (last set value). Hence I am a bit unsure about the 2nd sentence. Does it make sense to simplify the 2nd sentence above to something like this?

"If no handler is provided for a given Property, implementations are required to report the property value as is (e.g., set by writeProperty() or ThingProperty.value)"

</p>
</section>

<section> <h3>The <dfn>setPropertyWriteHandler()</dfn> method</h3>
<p>
Takes a <code>propertyName</code> as an optional string argument, and a <code>writeHandler</code> argument of type <a>PropertyWriteHandler</a>. Sets the handler function for writing the specified <a>Property</a> matched by <code>propertyName</code> if the <code>propertyName</code> is specified, otherwise sets it for writing any properties. Throws on error. Returns a reference to the same object for supporting chaining.
Takes <code>name</code> as string argument and <code>writeHandler</code> as argument of type <a>PropertyWriteHandler</a>. Sets the handler function for writing the specified <a>Property</a> matched by <code>name</code>. Throws on error. Returns a reference to the same object for supporting chaining.
</p>
<p>
There SHOULD be at most one write handler for any given <a>Property</a>. If no write handler is initialized for any given <a>Property</a>, implementations SHOULD implement default property update and notifying observers.
There SHOULD be at most one write handler for any given <a>Property</a> and newly added handlers replace the old handlers. If no write handler is initialized for any given <a>Property</a>, implementations SHOULD implement default property update and notifying observers on change.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to the previous comment the 2nd sentence might look like

"If no write handler is initialized for a given Property, implementations SHOULD set the property value with the provided new data and notify observers."

Maybe "default property update" means the same to you. IF so fine also.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My thinking was that the handler actually implements writing the property in a way known only to it (e.g. using local call such as GPIO or network etc). Or it may only want to implement some side-effects (hooks) to setting the property value. Of course the WoT runtime can always update the "proxy" property value it maintains (i.e. in your case you only have the "proxy" property value, basically a memory location that is not bound to HW).

That is why I used the term "default property update", to leave open what that actually means (until we define the algorithms), since it may be more than just updating a local memory location.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree. Makes sense. Let's leave it as is for now.

</p>
</section>

<section> <h3>The <dfn>setActionHandler()</dfn> method</h3>
<p>
Takes a <code>actionName</code> as an optional string argument, and an <code>action</code> argument of type <a>ActionHandler</a>. Sets the handler function for the specified <a>Action</a> matched by <code>actionName</code> if <code>actionName</code> is specified, otherwise sets it for any action. Throws on error. Returns a reference to the same object for supporting chaining.
Takes <code>name</code> as string argument and <code>action</code> as argument of type <a>ActionHandler</a>. Sets the handler function for the specified <a>Action</a> matched by <code>name</code>. Throws on error. Returns a reference to the same object for supporting chaining.
</p>
<p>
If provided, this callback function will implement invoking an <a>Action</a> and SHOULD be called by implementations when a request for invoking a <a>Action</a> is received from the underlying platform.
If provided, this callback function will implement invoking an <a>Action</a> and SHOULD be called by implementations when a request for invoking a <a>Action</a> is received from the underlying platform. The callback will receive a <code>parameters</code> dictionary argument.
</p>
<p>
There SHOULD be exactly one handler for any given <a>Action</a>. If no handler is initialized for any given <a>Action</a>, implementations SHOULD return error if the action is invoked by any client.
Expand Down Expand Up @@ -868,13 +868,14 @@ <h2>Examples</h2>
schema: '{ "type": "number" }'
});
// add server functionality
thing.setActionHandler( () => {
thing.setActionHandler("reset", () => {
console.log("Resetting maximum");
thing.writeProperty("max", 0.0);
}, "reset");

thing.start();

});
thing.start().then(() => {
thing.register();
});
// define Thing business logic
setInterval( async () => {
let mock = Math.random()*100;
thing.writeProperty("temperature", mock);
Expand All @@ -884,9 +885,8 @@ <h2>Examples</h2>
thing.emitEvent("onchange");
}
}, 1000);

} catch (err) {
console.log("Script error: " + err);
console.log("Error creating ExposedThing: " + err);
}
</pre>

Expand All @@ -896,16 +896,22 @@ <h2>Examples</h2>
// note that produce() fails if thingDescription contains error
let thing = WoT.produce(thingDescription);
// Interactions were added from TD
// add server functionality (a Property handler specifically for prop1)
thing.setPropertyReadHandler( () => {
console.log("Handling read request for prop1");
// WoT adds generic handler for reading any property
// define a specific handler for one property
let name = "examplePropertyName";
thing.setPropertyReadHandler(name, () => {
console.log("Handling read request for " + name);
return new Promise((resolve, reject) => {
resolve(Math.random(100));
})
}, "prop1");
let examplePropertyValue = 5;
resolve(examplePropertyValue);
},
e => {
console.log("Error");
});
});
thing.start();
} catch(err) {
console.log("Script error: " + err);
console.log("Error creating ExposedThing: " + err);
}
</pre>

Expand Down