Closed sebastiankb closed 5 years ago
This is tricky. The use case is valid, but I am not sure events are the best way for this. IMHO for the use case above the term "alarm" would suit better, at least for describing border conditions.
When speaking about generic conditions/rules/filtering, we have a similar construct in discovery in Scripting API: one can specify discovery filters that may contain a Thing fragment, or a query, or a condition to be satisfied. I think we'd need a vocabulary for expressing such filters that we could use for
Such vocabulary should support:
Implementation could be supported either at the source or at the client side, depending on the case.
In general there is a question about how to set filters. We need to be able to specify selection criteria for items in the TD, and also limit conditions for reporting states.
Another pattern is for the client to supply the filter as a payload to an Action, which then creates an Event and returns an Entity Description (ED) document that contains the subscription instructions (subscribeEvent).
If the TD defines an action that accepts a filter, that should be valid and possible. Now returning another (special) Thing Description (the ED) is a bit of overengineering IMHO but it could be valid and possible as well.
I would still favor conditional events as they are simpler, and could be mostly implemented with filtering at the client side, i.e. making a good use case for using Observable filter() and map() operations.
IMO supporting server side filters (client-specific) puts too much stress on runtimes (typically constrained on the server side). If say 200 subscribers supply different filters that need to be matched at source by the server runtime, it might get in trouble.
However, it should be fine when constraints are specified in a TD for an exposed Thing, for instance that it would generate an event (for every listener) if some condition is met.
Anyway, all of this should be at the discretion of the Thing designer, we should just make sure to provide a preferably simple way to cover the use case.
I remember in one of the WoT calls, @mjkoster introduced ideas about filtering. It included minimum period, maximum period for intervals, and value step, greater than, and less than, for value filtering. I think we can consider some of those as a starter.
The conditional notification parameters are defined in the IETF CoRE Dynlink draft: https://datatracker.ietf.org/doc/draft-ietf-core-dynlink/
In 9/21 TD telecon, @mkovatsc led the discussion, and it was agreed that we will need to experiment the idea of having three data schemas for events (one for subscription instantiation such as filtering, one for subscription control, and one for event data) both in online PlugFest and Lyon PlugFest.
Summarizing the use cases so far:
IMHO all these use cases could be modeled in similar ways. I agree with Matthias that we need to describe input (filter) data, output data and subscription (control object) metadata for these.
In practice, at least in Scripting we currently model these what are now called Observable
and Subscription
: Observables contain a subscribe()
method that accepts parameters/filters, and returns a Subscription
object that has events (or configures callbacks) for what to do on next item
, on error
, or on complete
, and has an unsubscribe()
(or cancel()
) method.
In this analogy, Property
and Event
simply implement Observable.
Also, Thing implements Observable (for TD changes).
The Thing.discover() method is explicitly there (as a special action).
(So far all these is already supported in Scripting API.)
In addition, at least progress-monitored actions could return a Subscription
object that allows monitoring (by onNext
), handling errors (by onError
), or completion (by onComplete
) and when supported, the cancel()
method.
Coming back to the Event issue, the agreed on proposal from the TD call was -- as @takuki wrote -- to have three schema elements. Let's just pick three terms to get started:
subscription
: any data that needs to be passed upon subscription, e.g., filters or message format for setting up Webhooksdata
: the schema of the Event instance messages pushed by the Thingcancellation
: any data that needs to be passed to cancel a subscription, e.g., a specific message to remove a WebhookAll three take a DataSchema
and are optional (i.e., if no data has to be passed to subscribe, there is no subscription
-- similar to Actions that do not have input
).
We use event in current TD and need to update correctly for TPAC plugfest. Could anyone check if following example is correct ?
(Before TPAC)
"events": {
"change": {
"@type": "iot:PropertyChangedEvent",
"label": "change",
"type":"object",
"properties": {
"operationStatus": {
"@type": "iot:OperationStatusChanged",
"type": "boolean"
},
....
},
"forms": [{
"href": "change",
"mediaType": "application/json"
}]
}
}
(At TPAC)
"events": {
"change": {
"@type": "iot:PropertyChangedEvent",
"title": "change",
"data": {
"type":"object",
"properties": {
"operationStatus": {
"@type": "iot:OperationStatusChanged",
"type": "boolean"
},
....
},
}
"forms": [{
"href": "change",
"mediaType": "application/json"
}]
}
}
Yes it is correct, just an extra comma at
}, } "forms":
@egekorkan Thanks a lot!
Coming back to the Event issue, the agreed on proposal from the TD call was -- as @takuki wrote -- to have three schema elements. Let's just pick three terms to get started: subscription: any data that needs to be passed upon subscription, e.g., filters or message format for setting up Webhooks data: the schema of the Event instance messages pushed by the Thing cancellation: any data that needs to be passed to cancel a subscription, e.g., a specific message to remove a Webhook All three take a DataSchema and are optional
I got questions at the TPAC whether do we really need subscription
and cancellation
exposed (at least in Scripting), what is the use case etc (for instance, even if needed, subscription
and cancellation
info could be encapsulated by servient implementation/protocol bindings). If protocol-dependent input is needed from clients, then the WoT abstraction is partial/fragile.
A TAG design recommendation is to try to avoid events exposing data. Instead, use events for notification and capture data changes in the target object (i.e. take the data carried over the network together with the notification and expose it as data property on the receiving end plus an event that notifies about the data has been changed, instead of being exposed as part of an event structure).
Also, there were concerns by TAG members that we should not overload the Event terminology further and we should consider renaming WoT Events to e.g. WoT Notifications (or find a better term).
We need to address these topics for the TAG review of Scripting, but it needs to be discussed here in TD and/or in WoT Architecture repo.
I would like us to retain the simplicity of the Web of Things, and allow subscribe and unsubscribe methods that take a handler function as a required argument. It is useful to pass information with events, and I don't think that developer's will confuse WoT events with HTML DOM events. However, if that turns out to be a major problem in practice, we could indeed use the term "notification" in place of "event" if this is really needed to get TD and Scripting API to REC.
We need to distinguish the scripting API for client apps to subscribe to events from what is going on at the protocol level. Some platforms may simply transmit all events and leave it to the client platform to deal with subscriptions.
One idea for apps to filter events is to pass a function in place of the event name (a string). The function could then return true when a given event is to be passed to the application's handler. I am not yet convinced this is quite what developers are seeking.
I can imagine use cases involving a taxonomy of many distinct events. We could then allow apps to subscribe to a non-root named node in the taxonomy. This would require an extension to the thing description specification to declare such taxonomies, so perhaps this is something to leave to a future version of the specifications.
We can wait for official TAG review comments on the terms, I just signaled the feedback. I am aware that TAG design principles primarily target browser APIs, but we should heed the advice when possible. We try to describe a generic interaction layer above protocols, but I see it has gaps like
I think these (and WoT Event definition in particular) need some more thought.
@draggett
I would like us to retain the simplicity of the Web of Things, and allow subscribe and unsubscribe methods that take a handler function as a required argument.
If you are asking to have a simple WoT-owned interface for sub/unsub that would operate with callbacks instead of events, we already have something like that (it can be improved, though), perhaps we could change the name Observable
to something with less negative connotations. I will file an issue in Scripting repo about this in particular (as presented at the TPAC, there are several options we could take).
WoT also has observable properties, and currently it does not allow specifying how to limit notifications. For example, for analyzing car trajectory in 2 dimensions (i.e. x and y), WoT client needs to observe this coordinate property of WoT Thing. WoT should allow the client to set up how often it wants to receive value change notification. It can be time-based, it can be value-based (such as distance).
Since WoT event is more about operational information such as alerts, it is discrete in nature, therefore, may not necessarily have the need to limit the notification frequency on the wire.
I recently discovered a complication at least for web browsers. When a browser tab is hidden, the browser will after a while close any open web socket connections. You have to use the page visibility API to listen for visibility change events and if needed re-open the connections. The challenge is that server platforms vary in their behaviour. ThingWeb has one web socket per property or event that have been subscribed to. Arena has one web socket or event source per thing. Things Gateway is similar but you need to send a subscribe message to the re-opened socket and hence need to track subscriptions similar to ThingWeb.
My implementation defines a platform neutral API that allows me to hide much of this in platform specific adaptation classes. I remain deeply skeptical about the ability of protocol binding templates to adequately express the behaviour of each platform, and prefer a simple unambiguous "platform" declaration in the thing description that gives a unique URL for each platform, where the URL should link to the platform's documentation, in my case to the GitHub project for Arena.
@draggett You comment has nothing to do with the description of the server/Thing, nor with this Issue.
a) The TD is not supposed to describe problems that you might have locally in your client. b) Exposing a Thing from an inactive tab in a Web browser is probably not a good idea to start with; at best, it makes a demonstrator for testing and education. c) Making sure WebSockets are established is exactly the responsibility of a runtime system that sits between the WoT Scirpting API and whatever platfom/system APIs you have -- in your case your code between the WoT Scripting API and the Web browser APIs. d) It sounds like you are not using the WoT Scripting API. In that case you can write whatever code you want as along as it understands TD. And as you write correctly, application authors then need to read the documentation of your platform. (This is why so many people called for a common runtime system.)
@mkovatsc - you are partly right. The TD just declares the properties, actions and events, and the protocols for accessing them. There are non-functional requirements for how clients and servers manage the network connections. In respect to a web page as a client, the users will expect the page to be live when the browser tab is made visible or when opening the screen of their laptop. Browsers by design reduce the energy expended by web pages, when tabs are hidden, e.g. throttling timers and closing sockets. TD and Scripting API specifications may thus need to cover non-functional requirements.
My own platform implements the WoT WG scripting API, and layers this over a platform neutral API for platform adaptors. This allows the test framework to interoperate with multiple Web of Things platforms. This will facilitate gathering implementation reports across multiple platforms including the Eclipse ThingWeb. I would be interested to know who else has worked on a client library for web pages that supports multiple web of things platforms?
FWIW a "WoT runtime" is quite similar to web workers.
@draggett
My own platform implements the WoT WG scripting API, and layers this over a platform neutral API for platform adaptors
From this I understand, that you use the Scripting API as the common denominator between different platforms, not the Thing Description. This confuses me because
We all agree that there needs to be adaption to specific platforms. This happens through the WoT Runtime implementation -- code that you also have. PlugFests so far have shown that this code can be generic around the central ("vanilla") protocols such as HTTP, CoAP, and MQTT. Instead of having specific code for each platform, the generic code is for each protocol only and then configured by the TD information.
On 9 Nov 2018, at 09:15, Matthias Kovatsch notifications@github.com wrote:
@draggett https://github.com/draggett My own platform implements the WoT WG scripting API, and layers this over a platform neutral API for platform adaptors
From this I understand, that you use the Scripting API as the common denominator between different platforms, not the Thing Description. This confuses me because ...
You’re misinterpreting what I say. You asked if I implement the scripting API and I said yes. The adaptation layer is below the TD and refers to the specific of the variations of how different platforms use the same protocols.
Dave Raggett dsr@w3.org http://www.w3.org/People/Raggett W3C Data Activity Lead & W3C champion for the Web of things
outdated and no longer active discussion here. Latest discussion on events can be found here #398
From the discussion at the Bundang F2F Meeting (init by @mkovatsc and @mjkoster):
Current definition of the interaction Event does not take any inputs such as you can do with Action definitions. However, such an input can be used, e.g., to define some filtering requirements such as thresholds, intervals, etc.
Example:
Please comment on this proposal?