Copyright © 2020-2025 World Wide Web Consortium. W3C® liability, trademark and permissive document license rules apply.
本规范定义了一个 配置文件机制和一组 配置文件, 使开箱即用的 互操作性能够在 Web Things 及其 消费者之间,在 Web of Things 上实现。
开箱即用的互操作性意味着,任何符合给定 配置文件的 消费者 都可以与任何符合相同 配置文件的 Thing 进行交互,而无需额外 定制。
配置文件是一份技术规范,它提供了一组 断言,合规的 消费者和 Things 必须符合这些断言。
配置文件机制提供了一种方式,用于表明
给定 Thing 符合一个或多个 配置文件,即在其
Thing
Description 的 profile 成员中引用这些
配置文件的
标识符。
本规范定义了三个配置文件:
本规范中定义的 配置文件 共享一组通用约束,这些 配置文件的实现也必须符合这些约束。这 包括对单位、日期格式、安全 机制、发现机制、链接关系和 错误的约束。
本规范的未来版本或扩展 规范可以定义其他配置文件。
本节描述本文档在 发布时的状态。当前 W3C 出版物和本技术报告 最新修订版的列表可在 W3C 标准和草案 索引中找到。
本文档由 Web of Things 工作 组作为工作草案发布,使用 推荐标准 轨道。
作为工作草案发布并不意味着 W3C 及其 成员的认可。
本文档是一份草案文档,可能随时被 更新、替换或 废弃。除非作为进行中的工作, 否则不适合引用本文档。
本文档由一个在 W3C 专利政策下运作的小组制作。 W3C 维护一份与该小组 交付物相关的任何 专利披露公开列表; 该页面还包括披露专利的 说明。任何实际知晓 某项专利且认为该专利包含必要 权利要求的个人,必须按照 W3C 专利政策第 6 节披露该信息。
本文档受 2025 年 8 月 18 日 W3C 流程 文档约束。
Web of Things (WoT) 旨在通过使用并扩展现有的、 标准化 Web 技术,来应对物联网 (IoT) 的碎片化。
W3C WoT Thing Description [wot-thing-description11] 规范定义了一种信息模型和基于 JSON 的 表示格式,用于描述互联设备的能力以及与其 通信所用的接口。Thing Descriptions 被 设计为与协议无关,并且足够灵活,能够 描述各种现有的(“棕地”)IoT 设备。
为了提供这种灵活性,Thing Description 规范包含了若干扩展 点,包括协议绑定、载荷绑定、 安全机制、链接关系和语义上下文。只要 设备的所有能力都可以使用 Thing Description 来描述,并且 消费者实现了所用的所有 扩展,则该消费者就应该能够与 该设备互操作。然而,这种可扩展架构的结果是, 任何给定的消费者只能与 可能的 Web Things 的一个子集互操作。
本规范旨在补充 Thing Description [wot-thing-description11] 规范,通过使用“配置文件”来实现临时互操作性。 配置文件规定了一组有限的 扩展和默认值,Thing 可以受这些扩展和默认值约束, 以保证与任何实现该 配置文件的消费者实现开箱即用的 互操作性。
配置文件 专门面向新的(“绿地”)实现而设计,在这些实现中, 开发者可以自由地符合规定性的 协议绑定和一组通用约束,从而 受益于这种额外层级的互操作性。
本规范的未来版本或扩展 规范可以定义其他配置文件。
Web of Things Interest Group 从代表各个 不同行业的利益相关方那里收集了 Web of Things 的用例。这包括垂直的、 特定领域的用例,以及适用于多个应用领域的 横向用例 [wot-usecases]。
若干特定领域 用例提到了对来自多个厂商的 设备进行轻松集成的需求。这对于需要 “多厂商系统集成”和“开箱即用互操作性”的 跨领域 用例尤其重要。
配置文件的一组 需求是从这些用例中推导出来的。
从较高层面看,开箱即用的互操作性意味着 消费者 被保证能够使用某个 Thing 的每一项能力,而无需针对该 Thing 进行 特定定制。
本规范中使用的开箱即用互操作性的完整定义 包含多个层级。下面的分类采用了“H2020 - CREATE-IoT Project - Recommendations for commonalities and interoperability profiles of IoT platforms” [H2020-CREATE-IoT] 报告中的术语。下面的定义经过调整,以反映 WoT 配置文件的范围。
技术互操作性通常 与通信协议以及这些协议运行所需的 基础设施相关。这意味着需要就一种共同协议 (例如 HTTP / TCP/IP)达成一致,并在 需要时提供额外的澄清。
句法互操作性通常 与数据格式和编码以及 压缩这些格式和编码的技术相关。WoT 中这些格式 和编码的示例包括 JSON、XML、JSON-LD、UTF-8 载荷。
语义互操作性与通信 参与方行为的共同理解相关。在配置文件上下文中, 它包括对(同步和异步)动作 语义的共同解释、共同的事件模型、如何设置/获取多个 属性、可写属性、共同的错误模型和 错误消息。
特定领域的本体,例如汽车和医疗设备的 语义互操作,超出了本 规范的范围。
在配置文件上下文中,组织互操作性 意味着任何符合给定配置文件的 消费者,都可以与任何符合 相同配置文件的 Thing 交互,而无需额外 定制。
组织互操作性还要求在安全、信任和隐私方面 采用共同商定的方法,即只有在应用这些共同条款和 条件时,才向 消费者提供 对 Things 的访问。
由各种工程师、厂商和 SDO 创建的设备, 只要满足配置文件规范的要求, 就可以与合规的消费者集成,而无需额外 定制。这可以跨基础设施、地区 和文化发挥作用。
除标记为非规范性的章节外,本规范中的所有编写 指南、图示、示例和注释均为非规范性。 本规范中的其他所有内容均为 规范性。
本文档中的关键词 MAY、MUST、MUST NOT、 OPTIONAL、RECOMMENDED、SHOULD 和 SHOULD NOT 只有在如 此处所示全部以大写形式出现时,才应 按照 BCP 14 [RFC2119] [RFC8174] 所述进行解释。
基本 WoT 术语,例如 Web Thing (Thing)、 消费者、 Thing Description、属性、动作、事件 和 协议 绑定,在 WoT Architecture 规范的第 3 节中定义 [wot-architecture11]。
为了符合某个配置文件,Web Thing MUST 符合该配置文件 规范中的所有规范性陈述。
为了表示给定的
Web
Thing 符合
一个或多个配置文件,
其 Thing
Description MUST 包含一个
profile 成员 [wot-thing-description11]。
profile 成员的
值 MUST 设置为一个有效 URI
[RFC3986],
用于标识单个配置文件,
或设置为一个有效 URI 数组,用于标识多个配置文件。
为了在
Thing Description 中使用 profile
成员,@context 成员 MUST
包含 anyURI
https://www.w3.org/2022/wot/td/v1.1,以
表示该文档正在使用 Thing
Description 规范的 1.1 版本。[wot-thing-description11]。
{
"@context": "https://www.w3.org/2022/wot/td/v1.1",
"id": "urn:dev:ops:32473-WoTLamp-1234",
"profile": "https://www.w3.org/2022/wot/profile/http-basic/v1",
"title": "My Lamp",
"description": "A web connected lamp",
...
}
{
"@context": "https://www.w3.org/2022/wot/td/v1.1",
"id": "urn:dev:ops:32473-WoTLamp-1234",
"profile": [
"https://www.w3.org/2022/wot/profile/http-basic/v1",
"https://www.w3.org/2022/wot/profile/http-sse/v1"
],
"title": "My Lamp",
"description": "A web connected lamp",
...
}
所有符合某个 配置文件 的 Things 和 消费者 MUST 满足 WoT Thing Description 1.1 规范 [wot-thing-description11] 中规定的断言,但文本为“TD 1.1 consumers MUST accept TDs satisfying the W3C WoT Thing Description 1.0 [wot-thing-description] specification.”的断言除外。
配置文件
SHOULD NOT 重新定义协议
绑定模板 [wot-binding-templates] 中的默认值。
例如,如果某个配置文件使用 HTTP 协议绑定,并且 HTTP
Binding Template 指定在 HTTP 协议绑定中,
readproperty 操作的
htv:methodName 默认值为 GET,则该
配置文件不应将该值重新定义为
POST。
配置文件
SHOULD NOT 要求 Thing 以一种未实现该
配置文件的消费者
会感到意外的方式响应。例如,配置文件可以为
queryaction 操作定义协议绑定的细节,
这些细节目前可能无法使用
Thing Description 中的
协议绑定模板完整描述(这是由于 WoT Thing Description 1.1
规范当前的限制),并且可以由合规的
消费者
使用;但 Thing
Description 暴露的任何其他
与动作相关的操作,仍应以未实现该配置文件的
消费者所期望的方式响应。
符合某个配置文件并不阻止 Web Thing 在其 Thing Description 中描述超出该配置文件所描述范围的其他能力和协议绑定, 只要它们符合该配置文件 的所有规范性断言即可。
仅仅因为某个Thing Description 声称其所描述的 Thing 符合给定的 配置文件, 消费者也不应假定 它实际上符合。例如,如果某个 Thing 未按规定 对给定操作作出响应,消费者应能够 优雅地恢复。
以下章节适用于本文档定义的 配置文件。
Thing Descriptions 的作者应注意,其所在 地理区域常用的单位并不具有全球适用性,并且可能导致 具有严重后果的误解。
如果
一个值具有物理量,则高度 RECOMMENDED 提供 unit。
对于用于全球 部署的设备,高度 RECOMMENDED 使用公制系统(SI 单位)。
除非另有
指定,所有日期和时间值 MUST 使用
[RFC3339] 中定义的
date-time 格式。
2022-09-21T23:20:50.52Z
为了减少歧义,RFC 3339 只 允许小时值在 00 到 23 之间(不包括 24), 并且时区表示为相对于 UTC 的数字偏移。 后缀“Z”应用于时间时表示 UTC 偏移为 00:00。
合规的 Web Things MUST 使用以下至少一种 安全方案 [wot-thing-description11]:
NoSecuritySchemeBasicSecuritySchemecode 或 client 流程的
OAuth2SecurityScheme
合规的消费者 MUST 支持以下所有 安全方案 [wot-thing-description11]:
NoSecuritySchemeBasicSecuritySchemecode 或 client 流程的
OAuth2SecurityScheme
oneOf 成员至少包含上述一种
方案的 ComboSecurityScheme
Thing MAY 实现多个安全方案。
如果某个 Thing 支持多个
安全方案,则它 MUST 使用
ComboSecurityScheme 通过 oneOf
成员枚举这些方案,使得一次只需要使用一个
安全方案。
对于
BasicSecurityScheme,“in”字段 MUST 要么省略,
要么被赋予 [wot-thing-description11] 中定义的默认
值“header”。
对于
BasicSecurityScheme,如果未给出“proxy”端点,
“name”字段 MUST 使用值
“Authorization”提供。
对于
BasicSecurityScheme,如果给出了“proxy”端点,
“name”字段 MUST 使用值
“Proxy-Authorization”提供。
合规的消费者 MUST 支持所有已实现安全方案的 安全引导,如 WoT Discovery [wot-discovery] 规范中安全 引导所定义。
合规的Things 如果需要 身份验证才能检索其 Thing Description,则 MUST 实现 安全引导,如 WoT Discovery [wot-discovery] 规范中安全 引导所定义。
Web Thing 的 Thing Description [wot-thing-description11] MUST 可通过由直接 引入机制 [wot-discovery] 提供的 HTTP URL [RFC9110],从 Thing Description Server [wot-architecture11] 检索。
links 成员中包含链接
[wot-thing-description11],
这些链接提供指向其他 Web 资源的
超链接。本节定义了 Link 的 rel 和
type 成员的特定组合,合规的消费者应以特定方式
解释这些组合。
| rel | type | 含义 |
|---|---|---|
icon |
image/* |
表示该 Thing 的图标 |
alternate |
text/html |
用于与该 Thing 交互的用户界面 |
service-doc |
text/plain 或 text/html
或 text/pdf |
该 Thing 的用户手册 |
item |
application/td+json |
目标 Thing 是此 Thing 的组件,或是此 Thing 所表示的 Things 集合中的成员 |
collection |
application/td+json |
此 Thing 是目标 Thing 的组件,或是目标 Thing 所表示的一组 Things 中的成员 |
如果消费者遇到一个 具有 "rel": "icon" 和 "type": "image/*" 的链接,并且它能够 渲染所提供格式的图像,则它 SHOULD 将该链接 解释为该 Thing 的图标并向用户显示。
如果消费者遇到一个 具有 "rel": "alternate" 和 "type": "text/html" 的链接,并且它能够 渲染 HTML 页面并接受用户输入,则它 SHOULD 将该链接解释为该 Thing 的用户 界面,并为用户提供一种方式以 跟随该链接,查看并与该 HTML 页面交互。
如果消费者遇到一个 具有 "rel": "service-doc" 且 "type": "text/plain"、"type": "text/html" 或 "type": "text/pdf" 的链接,并且能够 渲染所提供格式的文档,则它 SHOULD 将该链接解释为该 Thing 的用户 手册,并为用户提供一种方式以 跟随该链接并阅读该用户手册。
如果消费者遇到一个 具有 "rel": "item" 和 "type": "application/td+json" 的链接,并且能够 渲染 Things 的层次树,则它 should 将该链接解释为一个指示,表明目标是 当前 Thing 的子 Thing,并以对用户 有意义的方式呈现这一点。
如果消费者遇到一个 具有 "rel": "collection" 和 "type": "application/td+json" 的链接,并且 能够渲染 Things 的层次树,则它 should 将该链接解释为一个指示,表明目标 描述了一个 Thing(例如一组 Things、Things 系统或 Thing Directory),其中包含当前 Thing,并以对用户 有意义的方式呈现这一点。
如果 HTTP 配置文件的协议绑定中定义的任何操作 未成功,则 Web Thing MUST 发送一个带有 HTTP 错误 代码的 HTTP 响应,该错误代码描述失败原因。
错误响应 RECOMMENDED 使用以下 HTTP 错误代码之一:
400 Bad Request401 Unauthorized403 Forbidden404 Not Found500 Internal Server Error503 Service UnavailableWeb Thing MAY 出于
重定向、缓存或身份验证目的,以 3xx 状态码
响应。
Web Thing MUST NOT 以 300 Multiple
Choices 状态码响应。
Web Things MAY 以其他有效的 HTTP 错误代码
响应(例如 418 I'm a teapot)。 消费者 MAY 将其他有效的
HTTP 错误代码解释为
一个通用的 4xx 或 5xx 错误,而不赋予
特殊定义的行为。
如果 HTTP 错误响应 包含主体,则该主体的内容 MUST 符合 Problem Details 格式 [RFC7807]。
本节定义 HTTP Basic Profile,其中包括一个 协议 绑定,用于读取和写入属性,以及调用、 查询和取消动作。
此配置文件可以与 HTTP SSE Profile 或 HTTP Webhook Profile 一起使用,以便 提供用于观察属性和侦听 事件的操作。
为了 符合 HTTP Basic Profile,Web Things 和 消费者 MUST 还必须符合 通用约束 一节中的所有断言。
为了表示给定的
Web
Thing 符合 HTTP Basic Profile,其 Thing
Description MUST 具有一个 profile
成员 [wot-thing-description11],
其值为
https://www.w3.org/2022/wot/profile/http-basic/v1。
本节定义一个协议绑定,它 描述消费者如何使用通过 HTTP 协议 [RFC9112] 传输的 JSON [JSON] 载荷,与 Web Thing [wot-architecture11] 通信。
符合 HTTP Basic Profile 的消费者或Web Thing MUST 实现 此协议绑定。
本节中提供的示例描述了 消费者会如何与产生以下 Thing Description 的 Web Thing 通信:
{
"@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-basic/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": [{"href": "properties/on"}]
},
"level" : {
"type": "integer",
"title": "Brightness",
"description": "The level of light from 0-100",
"unit": "percent",
"minimum" : 0,
"maximum" : 100,
"forms": [{"href": "properties/level"}]
}
},
"actions": {
"fade": {
"title": "Fade",
"description": "Fade the lamp to a given level",
"synchronous": false,
"input": {
"type": "object",
"properties": {
"level": {
"title": "Brightness",
"type": "integer",
"minimum": 0,
"maximum": 100,
"unit": "percent"
},
"duration": {
"title": "Duration",
"type": "integer",
"minimum": 0,
"unit": "milliseconds"
}
}
},
"forms": [{"href": "actions/fade"}]
}
},
"forms": [
{
"op": ["readallproperties", "writemultipleproperties"],
"href": "properties"
},
{
"op": "queryallactions",
"href": "actions"
}
]
}
读取属性值时使用的属性资源 URL MUST 通过在 Thing Description 中定位对应 PropertyAffordance 内满足以下条件的 Form 来获得:
op 成员包含值
readproperty
href 成员值的 URI
scheme [RFC3986]
为
http 或 https
contentType 成员的值为
application/json
href 成员解析后的值随后 MUST 用作
属性资源的 URL。
为了读取属性的值, 消费者 MUST 向 Web Thing 发送具有以下内容的 HTTP 请求:
GETAccept 标头设置为
application/json
GET /things/lamp/properties/on HTTP/1.1
Host: mythingserver.com
Accept: application/json
如果 Web Thing 收到符合上述格式的 HTTP 请求,并且 消费者有权限 读取对应的属性,则在 成功读取该属性的值后, 它 MUST 发送具有以下内容的 HTTP 响应:
200Content-Type 标头设置为
application/json
HTTP/1.1 200 OK
Content-Type: application/json
false
写入属性值时使用的属性资源 URL MUST 通过在 Thing Description 中定位对应 PropertyAffordance 内满足以下条件的 Form 来获得:
op 成员包含值
writeproperty
href 成员值的 URI
scheme [RFC3986]
为
http 或 https
contentType 成员的值为
application/json
href 成员解析后的值随后 MUST 用作
属性资源的 URL。
为了写入属性的值, 消费者 MUST 向 Web Thing 发送具有以下内容的 HTTP 请求:
PUTContent-Type 标头设置为
application/json
PUT /things/lamp/properties/on HTTP/1.1
Host: mythingserver.com
Content-Type: application/json
true
HTTP/1.1 204 No Content
一次性读取所有属性值时使用的
properties 资源 URL
MUST 通过在
Thing
Description 的顶层
forms 成员中定位满足以下条件的
Form
来获得:
op 成员包含值
readallproperties
href 成员值的 URI
scheme [RFC3986]
为
http 或 https
contentType 成员的值为
application/json
href 成员解析后的值
随后 MUST 用作
properties 资源的 URL。
为了读取所有属性的值, 消费者 MUST 向 Web Thing 发送具有以下内容的 HTTP 请求:
GETAccept 标头设置为
application/json
GET /things/lamp/properties HTTP/1.1
Host: mythingserver.com
Accept: application/json
如果 Web Thing 收到符合上述格式的 HTTP 请求,则在成功读取 消费者有权限 访问的所有可读属性的值后, 它 MUST 发送具有以下内容的 HTTP 响应:
200Content-Type 标头设置为
application/json
HTTP/1.1 200 OK
Content-Type: application/json
{
"on": false,
"level": 100
}
一次性写入多个属性值时使用的
properties 资源 URL
MUST 通过在
Thing
Description 的顶层
forms 成员中定位满足以下条件的
Form
来获得:
op 成员包含值
writemultipleproperties
href 成员值的 URI
scheme [RFC3986]
为
http 或 https
contentType 成员的值为
application/json
href 成员解析后的值
随后 MUST 用作
properties 资源的 URL。
PUT /things/lamp/properties HTTP/1.1
Host: mythingserver.com
Content-Type: application/json
{
"on": true,
"level": 50
}
HTTP/1.1 204 No Content
排除 readmultipleproperties
操作是因为请求载荷格式较为复杂,
并且与 readproperty 和
readallproperties 相比并没有增加多少
功能。
writeallproperties 被排除,是因为它
只是
writemultipleproperties 的一个特殊情况。
调用动作时使用的动作资源 URL MUST 通过在 Thing Description 中定位对应 ActionAffordance 内满足以下条件的 Form 来获得:
op 成员的值为
invokeaction
href 成员值的 URI
scheme [RFC3986]
为
http 或 https
contentType 成员的值为
application/json
href 成员解析后的值 MUST 随后用作
动作资源的 URL。
为了在 Web Thing 上调用 动作, 消费者 MUST 向 Web Thing 发送具有以下内容的 HTTP 请求:
POSTAccept 标头设置为
application/json
Content-Type 标头设置为
application/json(仅当该动作具有
输入时)
POST /things/lamp/actions/fade HTTP/1.1
Host: mythingserver.com
Content-Type: application/json
Accept: application/json
{
"level": 100,
"duration": 5
}
如果
动作没有输入,则请求的
Content-type 标头
SHOULD NOT 设置,并且主体
should 为空。
有效的 JSON 值——例如
null、空引号
("")或空花括号({})——
可能是有效的动作输入,并不被认为是
“空”主体。
ActionAffordance 的 synchronous 成员 MUST 设置
为 true 或 false。
如果
ActionAffordance [wot-thing-description11]
的 synchronous 成员设置为 true,则 Web Thing MUST
以同步动作
响应进行响应。
如果
ActionAffordance [wot-thing-description11]
的 synchronous 成员设置为 false,则
Web Thing MUST 以异步
动作
响应进行响应。
对于
不预期在 HTTP 请求超时期限内
(例如 30 到 120 秒)完成执行的长时间运行动作,
Web Thing RECOMMENDED 以
异步动作响应进行响应,以便
消费者可以在初始
invokeaction 响应之后,继续通过对动态
创建的 ActionStatus 资源执行
queryaction 操作来监视动作请求的
状态。
对于 预期在 HTTP 请求超时期限内完成执行的 短时动作, Web Thing MAY 等待该 动作完成后再发送同步动作 响应。
如果
Web
Thing 在响应 invokeaction
请求之前尝试执行动作时遇到错误,
则它 MUST 发送
错误响应。
合规的
消费者 MUST 支持对初始
invokeaction 请求的所有三种
响应类型。
初始
请求之后,对 ActionStatus 资源上的后续操作的支持
是 OPTIONAL。
异步动作调用
请求的状态由
ActionStatus 对象表示,该对象包含以下
成员:
| 成员 | 描述 | 赋值 | 类型 |
|---|---|---|---|
status |
动作请求的状态。 | 必需 |
string(以下之一:
pending、running、
completed 或
failed)
|
output |
已完成动作的输出数据(如有),该数据
MUST
符合对应
ActionAffordance 的 output 数据
模式。
|
可选 | 任意类型 |
error |
与失败动作关联的错误消息(如有),它
MUST 使用 Problem Details 格式的 JSON
序列化
[RFC7807]
(仅在响应
queryaction 操作时需要)。
|
可选 | object |
href |
可由 queryaction 和
cancelaction 操作使用的
ActionStatus 资源的 [URL],
其
URI scheme [RFC3986]
MUST
解析为 http 或
https(仅在
异步
动作响应中需要)。
|
可选 | string |
timeRequested |
一个时间戳,指示 Thing 收到执行 动作请求的时间。(有关日期格式约束,参见日期 格式)。 | 可选 | string |
timeEnded |
一个时间戳,指示 Thing 成功 完成执行该动作,或执行该动作失败的时间。 (有关日期格式约束,参见日期格式)。 | 可选 | string |
如果为具有输出的动作提供同步动作响应, Web Thing MUST 发送具有以下内容的 HTTP 响应:
200Content-Type 标头设置为
application/json
HTTP/1.1 200 OK
Content-Type: application/json
20
如果为没有输出的动作提供同步动作响应, Web Thing MUST 发送具有以下内容的 HTTP 响应:
204Content-Type 标头未设置HTTP/1.1 204 No Content
有效的 JSON 值——例如
null、空引号
("")或空花括号({})
——可能是有效的动作输出,并不
被认为是“空”主体。
如果提供异步动作响应,
Web Thing MUST 发送包含
ActionStatus 资源 URL 的 HTTP 响应,
该 URL 的
URI
scheme [RFC3986]
MUST 解析为
http 或 https。该响应
MUST 具有:
201Content-Type 标头设置为
application/json
Location 标头设置为
ActionStatus 资源的 URL
ActionStatus
对象,其
href 成员设置为
ActionStatus 资源的 URL
HTTP/1.1 201 CREATED
Content-Type: application/json
Location: /things/lamp/actions/fade/123e4567-e89b-12d3-a456-426655
{
"status": "pending",
"href": "/things/lamp/actions/fade/123e4567-e89b-12d3-a456-426655",
"timeRequested": "2021-11-10T11:43:19.135Z"
}
在资源受限的环境中,较旧的
已完成/已失败动作的 ActionStatus 对象
MAY
被删除,以便为新调用的
动作腾出空间。
queryaction 操作用于查询
正在进行的动作请求的当前状态。
对
动作上的 invokeaction 操作提供
异步动作
响应的
Web
Thing
MUST 还支持在该同一
动作上的
queryaction 操作。 仅对
动作上的 invokeaction 操作提供
同步动作
响应的
Web
Thing SHOULD
NOT 支持在该同一
动作上的
queryaction 操作。
queryaction 操作中使用的
ActionStatus 资源 URL MUST 从
异步动作
响应的 Location 标头,或其主体中
ActionStatus 对象的 href 成员获得。
为了查询动作请求的状态, 消费者 MUST 向 Web Thing 发送具有以下内容的 HTTP 请求:
GETActionStatus 资源的 URL
Accept 标头设置为
application/json
GET /things/lamp/actions/fade/123e4567-e89b-12d3-a456-426655
Host: mythingserver.com
Accept: application/json
如果 Web
Thing 收到符合上述格式的 HTTP 请求,并且
消费者有权限
查询对应的 ActionStatus
资源,则在成功读取该动作请求的状态后,
它 MUST
发送具有以下内容的 HTTP 响应:
200Content-Type 标头设置为
application/json
ActionStatus
对象,表示动作请求的当前状态,
并以 JSON 序列化HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "running",
"timeRequested": "2021-11-10T11:43:19.135Z"
}
如果
被查询的动作执行失败,则
ActionStatus 对象的
status 成员 MUST 设置为
"failed"。 如果
被查询的动作执行失败,则
error 成员 MAY
提供符合 Problem Details 格式的
其他错误信息 [RFC7807]。
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "failed",
"error": {
"type": "https://mythingserver.com/docs/errors/invalid-level",
"title": "Invalid value for level provided",
"invalid-params": [
{
"name": "level",
"reason": "Must be a valid number between 0 and 100"
}
]
},
"timeRequested": "2021-11-10T11:43:19.135Z",
"timeEnded": "2021-11-10T11:43:20.513Z"
}
cancelaction 操作用于
取消正在进行的动作请求。
对
动作上的 invokeaction 操作提供
异步动作
响应的
Web
Thing
MAY 还支持在该同一
动作上的
cancelaction 操作。
仅对
动作上的 invokeaction 操作提供
同步动作
响应的
Web
Thing SHOULD
NOT 支持在该同一
动作上的
cancelaction 操作。
cancelaction 操作中使用的
ActionStatus 资源 URL MUST 从
异步动作
响应的 Location 标头,或其主体中
ActionStatus 对象的 href 成员获得。
DELETE /things/lamp/actions/fade/123e4567-e89b-12d3-a456-426655 HTTP/1.1
Host: mythingserver.com
HTTP/1.1 204 No Content
查询所有正在进行的动作请求状态时使用的
actions 资源 URL
MUST 通过在
Thing
Description 的顶层
forms 成员中定位满足以下条件的
Form
来获得:
op 成员包含值
queryallactions
href 成员值的 URI
scheme [RFC3986]
为
http 或 https
contentType 成员的值为
application/json
href 成员解析后的值 MUST 随后用作
actions 资源的 URL。
为了查询所有正在进行的动作 请求的状态,消费者 MUST 向 Web Thing 发送具有以下内容的 HTTP 请求:
GETAccept 标头设置为
application/json
GET /things/lamp/actions HTTP/1.1
Host: mythingserver.com
Accept: application/json
如果 Web Thing 收到符合上述格式的 HTTP 请求,则在成功检索 消费者有 权限访问的所有正在进行的动作请求的状态后, 它 MUST 发送具有以下内容的 HTTP 响应:
200Content-Type 标头设置为
application/json
ActionStatus 对象数组,
用于表示动作请求,并以 JSON 序列化。
结果 对象中的每个数组 MUST 按逆时间顺序排序,使得 最近的动作请求首先出现。
HTTP/1.1 200 OK
Content-Type: application/json
{
"fade": [
{
"status": "completed",
"href": "/things/lamp/actions/fade/123e4567-e89b-12d3-a456-426655",
"timeRequested": "2021-11-10T11:43:19.135Z",
"timeEnded": "2021-11-10T11:43:20.513Z"
},
{
"status": "failed",
"href": "/things/lamp/actions/fade/123e4567-e89b-12d3-a456-558329",
"timeRequested": "2021-11-10T11:42:15.133Z",
"timeEnded": "2021-11-10T11:42:22.524Z"
},
{
"status": "running",
"href": "/things/lamp/actions/fade/123e4567-e89b-12d3-a457-434656",
"timeRequested": "2021-11-10T11:41:53.351Z"
},
{
"status": "pending",
"href": "/things/lamp/actions/fade/123e4567-e89b-12d3-a457-ea9519",
"timeRequested": "2021-11-10T11:39:53.651Z"
}
]
}
cancelaction 操作取消时,其
ActionStatus 对象会被删除,并且无需
保留。对于所有其他动作请求,假定
Web Thing 会存储
ActionStatus 对象,以便之后可以通过
queryaction 或
queryallactions 操作查询其状态。
并不期望 ActionStatus 对象应
无限期保留;它们可以存储在
易失性内存中,并/或定期修剪。保留
ActionStatus
对象的时间长度预计是实现特定的,并且
可能取决于特定应用需求或
资源约束。
本节定义 HTTP SSE Profile,其中包括一个 协议 绑定,用于使用服务器发送事件 [EVENTSOURCE] 观察属性并侦听 事件。
此配置文件可以与 HTTP Basic Profile 一起使用, 以便提供读取和写入属性以及调用、 查询和取消动作的操作。
为了 符合 HTTP SSE Profile,Web Things 和 消费者 MUST 还必须符合 通用约束 一节中的所有断言。
为了表示给定的
Web
Thing 符合 HTTP SSE Profile,其 Thing
Description MUST 具有一个 profile
成员 [wot-thing-description11],
其值为
https://www.w3.org/2022/wot/profile/http-sse/v1。
本节定义一个协议绑定,它 描述消费者如何使用服务器发送事件 [EVENTSOURCE] 与 Web Thing [wot-architecture11] 通信。
符合 HTTP SSE Profile 的消费者或Web Thing MUST 实现此 协议绑定。
本节中提供的示例描述了 消费者会如何与产生以下 Thing Description 的 Web Thing 通信:
{
"@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-sse/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": [
{
"href": "properties/on",
"op": ["observeproperty", "unobserveproperty"],
"subprotocol": "sse"
}
]
},
"level" : {
"type": "integer",
"title": "Brightness",
"description": "The level of light from 0-100",
"unit": "percent",
"minimum" : 0,
"maximum" : 100,
"forms": [
{
"href": "properties/level",
"op": ["observeproperty", "unobserveproperty"],
"subprotocol": "sse"
}
]
}
},
"events": {
"overheated": {
"title": "Overheated",
"data": {
"type": "number",
"unit": "degree celsius"
},
"description": "The lamp has exceeded its safe operating temperature",
"forms": [{
"href": "events/overheated",
"subprotocol": "sse"
}]
}
},
"forms": [
{
"op": ["observeallproperties", "unobserveallproperties"],
"href": "properties",
"subprotocol": "sse"
},
{
"op": ["subscribeallevents", "unsubscribeallevents"],
"href": "events",
"subprotocol": "sse"
}
]
}
观察属性值时使用的属性资源 URL MUST 通过在 Thing Description 中定位对应 PropertyAffordance 内满足以下条件的 Form 来获得:
op 成员包含值
observeproperty
href 成员值的 URI
scheme [RFC3986]
为
http 或 https
subprotocol 成员的值
为 ssecontentType 成员的值为
application/json
href 成员解析后的值随后 MUST 用作
属性资源的 URL。
为了 观察属性,消费者 MUST 遵循服务器发送事件 [EVENTSOURCE] 规范,在属性资源的 URL 处与 Web Thing 打开连接。
这涉及消费者向 Web Thing 发送具有以下内容的 HTTP 请求:
GETAccept 标头设置为
text/event-stream
Connection 标头设置为
keep-alive
GET /things/lamp/properties/level HTTP/1.1
Host: mythingserver.com
Accept: text/event-stream
Connection: keep-alive
对于使用 JavaScript
[ECMASCRIPT]
实现并在暴露
EventSource 接口的运行时中执行的消费者,
可以使用
EventSource 构造函数发起服务器发送
事件连接。
const levelSource = new EventSource('/things/lamp/properties/level');
如果 Web Thing 收到符合上述格式的 HTTP 请求,并且 消费者有权限 观察对应的属性,则它 MUST 遵循服务器发送事件 [EVENTSOURCE] 规范,与 消费者保持打开的连接,并在指定 属性 的值每次变化时,将属性值推送给 消费者。
这涉及 Web Thing 首先向 消费者发送具有以下内容的 HTTP 响应:
200Content-Type 标头设置为
text/event-stream
HTTP/1.1 200 OK
Content-Type: text/event-stream
只要指定
属性的值在
Web
Thing 与消费者之间存在打开连接期间发生变化,
Web Thing MUST 使用服务器发送事件
[EVENTSOURCE]
规范中的事件流格式向
消费者发送属性值。 对于
发送的每条消息,Web Thing MUST 将
event 字段设置为
PropertyAffordance 的名称,并用以 JSON 序列化且
遵循
PropertyAffordance 中指定的数据模式的属性值填充 data
字段。 id
字段 SHOULD 设置为属性变化的唯一标识符,
以便在重新建立断开的连接时使用(见下文)。 RECOMMENDED
该标识符是一个表示属性变化发生时间的时间戳(有关日期格式约束,参见
日期格式)。
event: level\n
data: 42\n
id: 2021-11-17T15:33:20.827Z\n\n
如果
消费者与 Web Thing
之间的连接断开(除非是由于下面定义的
unobserve 操作所致),
消费者 MUST 按照
服务器发送事件规范
[EVENTSOURCE]
中列出的步骤重新建立连接。
连接
重新建立后,Web Thing SHOULD 在可能的情况下,发送自
消费者在
Last-Event-ID 标头中指定的最后一次变化以来发生的任何遗漏的
属性变化。
属性值以 JSON 序列化,并在
以 text/event-stream 格式序列化的服务器发送事件的
data 字段中提供。
HTTP 标头中使用的 text/event-stream 内容类型
被假定由 sse 子协议隐含,而嵌入的
application/json 内容类型则在 Form 的
contentType 成员中指明(应用默认值后)。
为了 停止观察属性,消费者 MUST 按服务器发送事件规范 [EVENTSOURCE] 的规定,终止与 Web Thing 的对应 服务器发送事件连接。
对于使用
JavaScript [ECMASCRIPT]
实现并在暴露
EventSource 接口的运行时中执行的
消费者,
可以使用
EventSource [EVENTSOURCE]
对象上的
close() 方法终止服务器发送
事件连接。
levelSource.close();
观察某个 Web Thing
的所有属性变化时使用的 properties 资源 URL
MUST 通过在
Thing
Description 的顶层
forms 成员中定位满足以下条件的
Form
来获得:
op 成员包含值
observeallproperties
href 成员值的 URI
scheme [RFC3986]
为
http 或 https
subprotocol 成员的值
为 ssecontentType 成员的值为
application/json
href 成员解析后的值
随后 MUST 用作
properties 资源的 URL。
为了观察 Web Thing 的所有属性变化, 消费者 MUST 遵循服务器发送事件 [EVENTSOURCE] 规范,在 properties 资源的 URL 处与 Web Thing 打开连接。
这涉及消费者向 Web Thing 发送具有以下内容的 HTTP 请求:
GETAccept 标头设置为
text/event-stream
Connection 标头设置为
keep-alive
GET /things/lamp/properties HTTP/1.1
Host: mythingserver.com
Accept: text/event-stream
Connection: keep-alive
对于使用
JavaScript [ECMASCRIPT]
实现并在暴露
EventSource 接口的运行时中执行的
消费者,
可以使用
EventSource 构造函数发起服务器发送
事件连接。
const lampPropertiesSource = new EventSource('/things/lamp/properties');
如果 Web Thing 收到符合上述格式的 HTTP 请求,则它 MUST 遵循 服务器发送事件 [EVENTSOURCE] 规范,与 消费者保持打开的连接,并向 消费者推送其有权限观察的所有 属性的新 属性值。
这涉及 Web Thing 首先向 消费者发送具有以下内容的 HTTP 响应:
200Content-Type 标头设置为
text/event-stream
HTTP/1.1 200 OK
Content-Type: text/event-stream
只要属性在
Web
Thing 与消费者之间存在打开连接期间发生变化,
Web
Thing MUST 使用服务器发送事件
[EVENTSOURCE]
规范中的事件流格式向
消费者发送新的
属性值。
对于发送的每条消息,Web Thing MUST 将
event 字段设置为
PropertyAffordance 的名称,并用新的属性值填充 data
字段。
属性数据 MUST 遵循
PropertyAffordance 中指定的数据模式,并且 MUST
以 JSON 序列化。
id 字段 SHOULD
设置为事件的唯一标识符,以便在
重新建立断开的连接时使用(见下文)。
RECOMMENDED 该
标识符是一个表示
属性变化发生时间的时间戳
(有关日期
格式约束,参见日期格式)。
event: level\n
data: 42\n
id: 2021-11-17T15:33:20.827Z\n\n
如果 消费者与
Web Thing 之间的连接断开(除非是由于下面定义的
unobserveallproperties
操作所致),消费者 MUST 按照服务器发送事件
规范 [EVENTSOURCE]
中列出的步骤重新建立连接。
连接重新建立后,Web Thing SHOULD 在可能的情况下,发送自
消费者在
Last-Event-ID 标头中指定的最后一次变化以来发生的任何遗漏的
属性变化。
属性值以 JSON 序列化,并在
以 text/event-stream 格式序列化的
服务器发送事件的 data 字段中提供。
HTTP 标头中使用的
text/event-stream 内容类型
被假定由
sse 子协议隐含,而嵌入的
application/json 内容类型则在 Form 的
contentType 成员中指明(应用
默认值后)。
为了取消观察所有属性,消费者 MUST 按照服务器发送事件规范 [EVENTSOURCE] 中指定的步骤,终止与 Web Thing 的 properties 端点之间的对应服务器发送事件连接。
对于使用
JavaScript [ECMASCRIPT]
实现并在暴露
EventSource 接口的运行时中执行的
消费者,
可以使用
EventSource [EVENTSOURCE]
对象上的
close() 方法终止服务器发送
事件连接。
lampPropertiesSource.close();
HTTP SSE Profile 使用服务器发送事件 [EVENTSOURCE] 作为一种机制, 使消费者能够订阅由 Web Thing 发出的事件。
消费者不需要
实现服务器发送事件规范中的
EventSource JavaScript API,也可以符合
此配置文件。任何编程语言都可以用于
消费事件流。
订阅事件时使用的事件资源 URL MUST 通过在 Thing Description 中定位对应 EventAffordance 内满足以下条件的 Form 来获得:
op 成员包含值
subscribeevent
href 成员值的 URI
scheme [RFC3986]
为
http 或 https
subprotocol 成员的值
为 ssecontentType 成员的值为
application/json
href 成员解析后的值随后 MUST 用作
事件资源的 URL。
为了 订阅事件,消费者 MUST 遵循服务器发送事件 [EVENTSOURCE] 规范,在事件资源的 URL 处与 Web Thing 打开连接。
这涉及消费者向 Web Thing 发送具有以下内容的 HTTP 请求:
GETAccept 标头设置为
text/event-stream
Connection 标头设置为
keep-alive
GET /things/lamp/events/overheated HTTP/1.1
Host: mythingserver.com
Accept: text/event-stream
Connection: keep-alive
对于使用
JavaScript [ECMASCRIPT]
实现并在暴露
EventSource 接口的运行时中执行的
消费者,
可以使用
EventSource 构造函数发起服务器发送
事件连接。
const overheatedEventSource = new EventSource('/things/lamp/events/overheated');
如果 Web Thing 收到符合上述格式的 HTTP 请求,并且 消费者有权限 订阅对应的事件,则它 MUST 遵循 服务器发送事件 [EVENTSOURCE] 规范,与 消费者保持打开的连接,并在指定类型的事件发出时 将事件数据推送给 消费者。
这涉及 Web Thing 首先向 消费者发送具有以下内容的 HTTP 响应:
200Content-Type 标头设置为
text/event-stream
HTTP/1.1 200 OK
Content-Type: text/event-stream
只要指定类型的事件在
Web Thing 与
消费者之间存在打开连接期间发生,
Web Thing MUST 使用服务器发送事件
[EVENTSOURCE]
规范中的事件流格式向
消费者发送事件数据。
对于
发送的每条消息,Web Thing MUST 将
event 字段设置为
EventAffordance 的名称,并用事件数据(如有)填充 data
字段。 事件数据
MUST 遵循
EventAffordance 中指定的数据
模式,并以 JSON 序列化。
id
字段 SHOULD 设置为事件的唯一标识符,
以便在重新建立断开的连接时使用(见下文)。
RECOMMENDED 该
标识符是一个表示事件发生时间的时间戳(有关日期格式约束,参见
日期格式)。
event: overheated\n
data: 90\n
id: 2021-11-16T16:53:50.817Z\n\n
如果
消费者与 Web Thing
之间的连接断开(除非是由于下面定义的
unsubscribeevent
操作所致),消费者 MUST 按照服务器发送事件
规范 [EVENTSOURCE]
中列出的步骤重新建立连接。
连接
重新建立后,Web Thing SHOULD 在可能的情况下,发送自
消费者在
Last-Event-ID 标头中指定的最后一个事件以来发生的任何遗漏
事件。
事件载荷以 JSON 序列化,并在
以 text/event-stream 格式序列化的
服务器发送事件的 data 字段中提供。
HTTP 标头中使用的
text/event-stream 内容类型
被假定由
sse 子协议隐含,而嵌入的
application/json 内容类型则在 Form 的
contentType 成员中指明(应用
默认值后)。
为了 取消订阅事件,消费者 MUST 按服务器发送事件规范 [EVENTSOURCE] 的规定,终止与 Web Thing 的对应 服务器发送事件连接。
对于使用
JavaScript [ECMASCRIPT]
实现并在暴露
EventSource 接口的运行时中执行的
消费者,
可以使用
EventSource [EVENTSOURCE]
对象上的
close() 方法终止服务器发送
事件连接。
overheatedEventSource.close();
订阅由某个 Web Thing
发出的所有事件时使用的 events 资源 URL
MUST 通过在
Thing
Description 的顶层
forms 成员中定位满足以下条件的
Form
来获得:
op 成员包含值
subscribeallevents
href 成员值的 URI
scheme [RFC3986]
为
http 或 https
subprotocol 成员的值
为 ssecontentType 成员的值为
application/json
href 成员解析后的值
随后 MUST 用作
events 资源的 URL。
为了 订阅由 Web Thing 发出的所有 事件,消费者 MUST 遵循 服务器发送事件 [EVENTSOURCE] 规范,在 events 资源的 URL 处与 Web Thing 打开连接。
这涉及消费者向 Web Thing 发送具有以下内容的 HTTP 请求:
GETAccept 标头设置为
text/event-stream
Connection 标头设置为
keep-alive
GET /things/lamp/events HTTP/1.1
Host: mythingserver.com
Accept: text/event-stream
Connection: keep-alive
对于使用
JavaScript [ECMASCRIPT]
实现并在暴露
EventSource 接口的运行时中执行的
消费者,
可以使用
EventSource 构造函数发起服务器发送
事件连接。
const lampEventsSource = new EventSource('/things/lamp/events');
如果 Web Thing 收到符合上述格式的 HTTP 请求,则它 MUST 遵循 服务器发送事件 [EVENTSOURCE] 规范,与 消费者保持打开的连接,并向 消费者推送其有权限 订阅的所有事件类型的事件 数据。
这涉及 Web Thing 首先向 消费者发送具有以下内容的 HTTP 响应:
200Content-Type 标头设置为
text/event-stream
HTTP/1.1 200 OK
Content-Type: text/event-stream
只要事件在 Web Thing 与
消费者之间存在打开连接期间发生,
Web Thing MUST 使用服务器发送事件
[EVENTSOURCE]
规范中的
事件流格式向
消费者
发送事件数据。
对于发送的每条消息,Web Thing MUST 将
event 字段设置为
EventAffordance 的名称,并用事件数据(如有)填充 data
字段。
事件数据 MUST 遵循
EventAffordance 中指定的数据
模式,并以 JSON 序列化。
id 字段 SHOULD
设置为事件的唯一标识符,以便在
重新建立断开的连接时使用(见下文)。
RECOMMENDED 该
标识符是一个表示事件发生时间的时间戳(有关日期格式约束,参见
日期格式)。
event: overheated\n
data: 90\n
id: 2021-11-16T16:53:50.817Z\n\n
如果 消费者与
Web Thing 之间的连接断开(除非是由于下面定义的
unsubscribeallevents
操作所致),消费者 MUST 按照服务器发送事件
规范 [EVENTSOURCE]
中列出的步骤重新建立连接。
连接重新建立后,Web Thing SHOULD 在可能的情况下,发送自
消费者在
Last-Event-ID 标头中指定的最后一个事件以来发生的任何遗漏
事件。
事件载荷以 JSON 序列化,并在
以 text/event-stream 格式序列化的
服务器发送事件的 data 字段中提供。
HTTP 标头中使用的
text/event-stream 内容类型
被假定由
sse 子协议隐含,而嵌入的
application/json 内容类型则在 Form 的
contentType 成员中指明(应用
默认值后)。
为了取消订阅所有事件,消费者 MUST 按照服务器发送事件规范 [EVENTSOURCE] 中指定的步骤,终止与 Web Thing 的 events 端点之间的对应 服务器发送事件连接。
对于使用
JavaScript [ECMASCRIPT]
实现并在暴露
EventSource 接口的运行时中执行的
消费者,
可以使用
EventSource [EVENTSOURCE]
对象上的
close() 方法终止服务器发送
事件连接。
lampEventsSource.close();
本节定义 HTTP Webhook Profile,其中包括一个 协议 绑定,用于使用 Webhooks 观察属性并侦听 事件。
HTTP Webhook Profile MAY 与 HTTP Basic Profile 结合使用,以便提供读取和写入 属性以及调用、查询和取消动作的操作。
HTTP Webhook Profile MAY 作为 HTTP SSE Profile 的替代事件机制使用。
为了 符合 HTTP Webhook Profile,Web Things 和 消费者 MUST 还必须 符合 通用约束 一节中的所有断言。
为了实现 HTTP Webhook Profile, Thing 和 消费者都必须能够同时作为 HTTP 客户端和 HTTP 服务器,并且能够通过 网络相互访问。这在所有部署 场景中可能并不总是可行。
为了表示给定的
Web
Thing 符合
HTTP Webhook Profile,其 Thing
Description MUST 具有一个 profile
成员 [wot-thing-description11],
其值为
https://www.w3.org/2022/wot/profile/http-webhook/v1。
本节定义一个协议绑定,它 描述消费者和 Web Thing 如何使用 Webhooks 通信。
符合 HTTP Webhook Profile 的消费者或Web Thing MUST 实现 此协议绑定。
本节中提供的示例描述了 消费者会如何与产生以下 Thing Description 的 Web Thing 通信 [wot-thing-description11]:
{
"@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"
}
]
}
观察属性值时使用的 property 资源 URL MUST 通过在 Thing Description [wot-thing-description11] 中定位对应 PropertyAffordance 内满足以下条件的 Form 来获得:
op 成员包含值
observeproperty
href 成员值的 URI
scheme [RFC3986]
为
http 或 https
contentType 成员的值为
application/json
subprotocol 成员的值
为 webhook
href 成员解析后的值
随后 MUST 用作
property 资源的 URL。
POST /things/lamp/properties/level HTTP/1.1
Host: mythingserver.com
Content-Type: application/json
{
callbackURL: "https://myconsumer.com/listeners/d629c54e-a919-463b-8680-602a21f91fe9"
}
HTTP/1.1 201 Created
Location: /things/properties/level/74353483-3997-437a-a4f5-84d03784e517
POST /listeners/d629c54e-a919-463b-8680-602a21f91fe9 HTTP/1.1
Host: myconsumer.com
Date: Fri, 4 Jul 2025 12:48:00 GMT
Content-type: application/json
Link: <https://mythingserver.com/things/mylamp1/properties/level>; rel="self"
90
HTTP/1.1 200 OK
为了取消属性的观察订阅, 消费者 MUST 向 Web Thing 发送具有以下内容的 HTTP 请求:
DELETEobserveproperty
操作期间 HTTP 响应的
Location 标头中提供的订阅 URL
DELETE /things/properties/level/74353483-3997-437a-a4f5-84d03784e517 HTTP/1.1
Host: mythingserver.com
如果 Web Thing 收到符合上述格式的 HTTP 请求, 并且存在使用所提供 URL 的属性观察订阅, 则在成功取消该订阅后, Web Thing MUST 向 消费者发送具有以下内容的 HTTP 响应:
204 No
ContentHTTP/1.1 204 No Content
观察某个 Web Thing
的所有属性值时使用的
properties 资源 URL
MUST 通过在
Thing
Description [wot-thing-description11]
的顶层
forms 成员中定位满足以下条件的
Thing
Description 内的
Form
来获得:
op 成员包含值
observeallproperties
href 成员值的 URI
scheme [RFC3986]
为
http 或 https
contentType 成员的值为
application/json
subprotocol 成员的值
为 webhook
href 成员解析后的值
随后 MUST 用作
properties 资源的 URL。
POST /things/lamp/properties HTTP/1.1
Host: mythingserver.com
Content-Type: application/json
{
callbackURL: "https://myconsumer.com/listeners/aa2d8e1f-dc6a-4fe0-a5c0-a42d9f532699"
}
如果 Web Thing 收到符合上述格式的 HTTP 请求,并且 消费者有权限 观察该 Thing 的 属性,则在 成功注册回调 URL 后,它 MUST 向 消费者发送具有以下内容的 HTTP 响应:
HTTP/1.1 201 Created
Location: /things/properties/a84fc5df-2667-4db2-a767-feb4640f2cf7
当 properties 观察订阅处于 已注册状态时,只要任何可观察 属性的值发生变化, Web Thing MUST 向进行观察的 消费者发送具有以下内容的 HTTP 请求:
POSTContent-Type 标头设置为
application/json
Link 标头,其中 URL 设置为
对应
PropertyAffordance 的 URL,并且 rel 设置为
self
Date 标头由用户代理自动设置为
属性变化的时间,使用 [rfc9110] 中的 HTTP
Date 格式
POST /listeners/aa2d8e1f-dc6a-4fe0-a5c0-a42d9f532699 HTTP/1.1
Host: myconsumer.com
Date: Fri, 4 Jul 2025 12:56:00 GMT
Content-type: application/json
Link: <https://mythingserver.com/things/mylamp1/properties/level>; rel="self"
86
HTTP/1.1 200 OK
为了取消对所有属性的观察, 消费者 MUST 向 Web Thing 发送具有以下内容的 HTTP 请求:
DELETEobserveallproperties
操作期间 HTTP 响应的
Location 标头中提供的订阅 URL
DELETE /things/properties/a84fc5df-2667-4db2-a767-feb4640f2cf7 HTTP/1.1
Host: mythingserver.com
如果 Web Thing 收到符合上述格式的 HTTP 请求, 并且存在使用所提供 URL 的 properties 观察订阅, 则在成功取消该观察订阅后, Web Thing MUST 向 消费者发送具有以下内容的 HTTP 响应:
204 No
ContentHTTP/1.1 204 No Content
订阅事件时使用的 event 资源 URL MUST 通过在 Thing Description [wot-thing-description11] 中定位对应 EventAffordance 内满足以下条件的 Form 来获得:
op 成员包含值
subscribeevent
href 成员值的 URI
scheme [RFC3986]
为
http 或 https
contentType 成员的值为
application/json
subprotocol 成员的值
为 webhook
href 成员解析后的值 MUST 随后用作
event 资源的 URL。
POST /things/lamp/events/overheated HTTP/1.1
Host: mythingserver.com
Content-Type: application/json
{
callbackURL: "https://myconsumer.com/listeners/e79dd0a5-4537-4ded-a10f-bb4eb2aca28d"
}
如果 Web Thing 收到符合上述格式的 HTTP 请求,并且 消费者有权限 订阅对应的事件,则在 成功注册回调 URL 后,它 MUST 向 消费者发送具有以下内容的 HTTP 响应:
201 CreatedLocation 标头设置为一个唯一 URL,
表示单独的事件订阅,供
消费者之后
取消该订阅时使用。
HTTP/1.1 201 Created
Location: /things/events/overheated/ce527faa-a5ab-4f03-8f85-e4411d13edb5
当事件订阅处于已注册状态时, 只要被监视的事件实例发生, Web Thing MUST 向已订阅的 消费者发送具有以下内容的 HTTP 请求:
POSTContent-Type 标头设置为
application/json(仅当事件具有
数据载荷时)
Link 标头,其中 URL 设置为
对应 event 资源的 URL,并且
rel 设置为 self
Date 标头由用户代理自动设置为
事件发生的时间,使用 [rfc9110] 中的 HTTP
Date 格式
如果事件不包含数据载荷,则请求的
Content-Type 标头
SHOULD NOT 设置,并且主体
should 为空。
有效的 JSON 值——例如
null、空引号
("")或空花括号({})——
可能是有效的数据载荷,并不被认为是
“空”主体。
POST /listeners/e79dd0a5-4537-4ded-a10f-bb4eb2aca28d HTTP/1.1
Host: myconsumer.com
Date: Fri, 4 Jul 2025 16:46:00 GMT
Content-type: application/json
Link: <https://mythingserver.com/things/mylamp1/events/overheated>; rel="self"
90
HTTP/1.1 200 OK
为了取消对事件的订阅, 消费者 MUST 向 Web Thing 发送具有以下内容的 HTTP 请求:
DELETEsubscribeevent
操作期间 HTTP 响应的
Location 标头中提供的订阅 URL
DELETE /things/events/overheated/ce527faa-a5ab-4f03-8f85-e4411d13edb5 HTTP/1.1
Host: mythingserver.com
如果 Web Thing 收到符合上述格式的 HTTP 请求, 并且存在使用所提供 URL 的事件订阅, 则在成功取消该订阅后, Web Thing MUST 向 消费者发送具有以下内容的 HTTP 响应:
204 No
ContentHTTP/1.1 204 No Content
订阅某个 Web Thing 的所有
事件时使用的 events 资源 URL
MUST 通过在
Thing
Description [wot-thing-description11]
的顶层
forms 成员中定位满足以下条件的
Thing
Description 内的
Form
来获得:
op 成员包含值
subscribeallevents
href 成员值的 URI
scheme [RFC3986]
为
http 或 https
contentType 成员的值为
application/json
subprotocol 成员的值
为 webhook
href 成员解析后的值
随后 MUST 用作
events 资源的 URL。
POST /things/lamp/events HTTP/1.1
Host: mythingserver.com
Content-Type: application/json
{
callbackURL: "https://myconsumer.com/listeners/bdd2aa13-387b-4c97-9725-52294a9fa5a9"
}
如果 Web Thing 收到符合上述格式的 HTTP 请求,并且 消费者有权限 订阅该 Thing 的 事件,则在 成功注册回调 URL 后,它 MUST 向 消费者发送具有以下内容的 HTTP 响应:
201 CreatedLocation 标头设置为一个唯一 URL,
表示单独的事件订阅,供
消费者之后
取消该订阅时使用。
HTTP/1.1 201 Created
Location: /things/events/929dbb69-eb66-46df-a0fe-93701d82e7ea
当 events 订阅处于已注册状态时, 只要事件发生,Web Thing MUST 向 已订阅的消费者发送具有以下内容的 HTTP 请求:
POSTContent-Type 标头设置为
application/json(仅当事件
包含数据载荷时)
Link 标头,其中 URL 设置为
对应 event 资源的 URL,并且
rel 设置为 self
Date 标头由用户代理自动设置为
事件发生的时间,使用 [rfc9110] 中的 HTTP
Date 格式
如果事件不包含数据载荷,则请求的
Content-type 标头
SHOULD NOT 设置,并且主体
should 为空。
有效的 JSON 值——例如
null、空引号
("")或空花括号({})——
可能是有效的数据载荷,并不被认为是
“空”主体。
POST /listeners/bdd2aa13-387b-4c97-9725-52294a9fa5a9 HTTP/1.1
Host: myconsumer.com
Date: Fri, 4 Jul 2025 17:04:00 GMT
Content-type: application/json
Link: <https://mythingserver.com/things/mylamp1/events/overheated>; rel="self"
86
HTTP/1.1 200 OK
为了取消对所有事件的订阅, 消费者 MUST 向 Web Thing 发送具有以下内容的 HTTP 请求:
DELETEsubscribeallevents
操作期间 HTTP 响应的
Location 标头中提供的订阅 URL
DELETE /things/events/929dbb69-eb66-46df-a0fe-93701d82e7ea HTTP/1.1
Host: mythingserver.com
如果 Web Thing 收到符合上述格式的 HTTP 请求, 并且存在使用所提供 URL 的 events 订阅, 则在成功取消该 events 订阅后, Web Thing MUST 向 消费者发送具有以下内容的 HTTP 响应:
204 No
ContentHTTP/1.1 204 No Content
WoT Architecture [wot-architecture11] 和 WoT Thing Description [wot-thing-description11] 规范中的隐私考虑 SHOULD 被纳入 考量。
有关实现建议,另请参阅 WoT Security and Privacy Guidelines [wot-security]。
WoT Architecture [wot-architecture11] 和 WoT Thing Description [wot-thing-description11] 规范中的安全考虑 SHOULD 被纳入 考量。
有关实现建议,另请参阅 WoT Security and Privacy Guidelines [wot-security]。
Thing Description 各层级
title 和 description 成员的值可
用于生成用户界面,因此 SHOULD 是人类可读的
字符串,并且在必要时也可由辅助技术
渲染。
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in: