Add a schema for unobserve/observe property
relu91 opened this issue · 4 comments
Since we have schemas defined for subscribing and unsubscribing for events, I think it makes sense to have inputs for the corresponding operations in Properties. Protocol used for subscribe events might be used for observing and therefore might share the same requirements regarding inputs.
Some thoughts from the TD Call with @danielpeintner and @mjkoster :
- Without changing anything in the spec, there are the following solutions:
- Modeling properties that are observable and require payloads for subscription or cancellation should be done as events. The link between that property and event would not be possible to express in the current version. This is also going against an affordance that can be interacted with in different ways.
- The payloads are described in the forms with some protocol-specific keyword, e.g. a custom HTTP header that has the subscription id when you want to unobserve. This needs to be exposed to the application layer, which is not something we do. Currently, forms contain only static data.
- BACnet has this issue already where we are using uriVariables in the wrong way for subscribeCOV
- If we change the spec, we need the concrete use case that needs it. If not, Scripting API can get around this by defining a "PropertySubscription" interface. Some solutions:
- put multiple schemas into the property, each with an input and output. Like events but more detailed with top level names like
"read","write","observe". This would imply quite a lot of changes but would also address #875 . Also, the case where all of these operations having the same schema needs to be expressed in a way, e.g. reading, writing and observe data is just a number. - extend the forms with similar fields to
responseoradditionalResponsesbut more specific to the operations
- put multiple schemas into the property, each with an input and output. Like events but more detailed with top level names like
If we change the spec, we need the concrete use case that needs it.
I think if we dig into the original use case for having this schemas for events is quite easy to find an use case for properties.
extend the forms with similar fields to response or additionalResponses but more specific to the operations
Why do this when the solution is simply adding those two new schemas?
I think if we dig into the original use case for having this schemas for events is quite easy to find an use case for properties.
That is long ago, sadly. We did not work use case driven at the time. I doubt there will be any documentation why they exist.
Why do this when the solution is simply adding those two new schemas?
That was just a proposal as that can serve the same purpose while being quite uglier. Adding other schemas is not so simple either as events already have 3 schemas separated but property has 1 that is embedded into the affordance (its own issue...). Even events are problematic with the current 3 when you consider the return of a subscription request.
I've come across this again when trying to re-work the HTTP Webhook Profile.
There are subscription and cancellation data schemas for an EventAffordance, but not for a PropertyAffordance. This means there is no obvious way to describe the payload of an observeproperty request for Webhooks. In other protocol bindings there may also be the need to define the payload of an unobserveproperty operation.
It's also not clear to me how to describe the subscribe/cancellation data schema for subscribeallevents, unsubscribeallevents, obeserveallproperties and unobserveallproperties See also: #1665.
See the example Thing Description below and note that there is a subscription member for the "overheated" event, but not for either of the properties, and it's not clear what the data schema of the observeallproperties and subscribeallevents meta operations would be:
{
"@context": "https://www.w3.org/2022/wot/td/v1.1",
"id": "https://mywebthingserver.com/things/lamp",
"profile": [
"https://www.w3.org/2022/wot/profile/http-webhook/v1",
],
"base": "https://mywebthingserver.com/things/lamp/",
"title": "My Lamp",
"description": "A web connected lamp",
"securityDefinitions": {
"oauth2": {
"scheme": "oauth2",
"flow": "code",
"authorization": "https://mywebthingserver.com/oauth/authorize",
"token": "https://mywebthingserver.com/oauth/token"
}
},
"security": "oauth2",
"properties": {
"on": {
"type": "boolean",
"title": "On/Off",
"description": "Whether the lamp is turned on",
"forms": [
{
"op": "observeproperty",
"href": "properties/on",
"subprotocol": "webhook",
"contentType": "application/json",
"htv:methodName": "POST"
},
{
"op": "unobserveproperty",
"href": "properties/on/{subscriptionID}",
"subprotocol": "webhook",
"htv:methodName": "DELETE"
}
]
},
"level" : {
"type": "integer",
"title": "Brightness",
"description": "The level of light from 0-100",
"unit": "percent",
"minimum" : 0,
"maximum" : 100,
"forms": [
{
"op": "observeproperty",
"href": "properties/level",
"subprotocol": "webhook",
"contentType": "application/json",
"htv:methodName": "POST"
},
{
"op": "unobserveproperty",
"href": "properties/level/{subscriptionID}",
"subprotocol": "webhook",
"htv:methodName": "DELETE"
}
]
},
},
"events": {
"overheated": {
"title": "Overheated",
"data": {
"type": "number",
"unit": "degree celsius"
},
"description": "The lamp has exceeded its safe operating temperature",
"subscription": {
"type": "object",
"properties": {
"callbackURL": {
"type": "string",
"format": "uri",
"description": "Callback URL provided by subscriber for Webhook notifications."
}
}
}
"forms": [
{
"op": "subscribeevent",
"href": "events/overheated",
"subprotocol": "webhook",
"contentType": "application/json",
"htv:methodName": "POST"
},
{
"op": "unsubscribeevent",
"href": "events/overheated/{subscriptionID}",
"subprotocol": "webhook",
"htv:methodName": "DELETE"
}
]
}
},
"forms": [
{
"op": "observeallproperties",
"href": "properties",
"subprotocol": "webhook",
"htv:methodName": "POST"
},
{
"op": "unobserveallproperties",
"href": "properties/{subscriptionID}",
"suprotocol": "webhook",
"htv:methodName": "DELETE"
},
{
"op": "subscribeallevents",
"href": "events",
"subprotocol": "webhook",
"htv:methodName": "POST"
},
{
"op": "unsubscribeallevents",
"href": "events/{subscriptionID}",
"suprotocol": "webhook",
"htv:methodName": "DELETE"
}
]
}