@mhome/app-facade-protocol 1.66.0 → 1.71.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -2
- package/contract/entity-presentation-v1.md +1 -1
- package/contract/resource-read-v1.md +75 -0
- package/fixtures/group.conformance.json +383 -0
- package/fixtures/interaction-flow.conformance.json +19 -0
- package/fixtures/presentation/cases.json +521 -179
- package/fixtures/routing/cases.json +32 -0
- package/manifest/app-facade.v1.json +30 -2
- package/manifest/authorization.v1.json +18 -10
- package/manifest/host-provision-targets.v1.json +1 -1
- package/manifest/hub-targets.v1.json +1 -1
- package/manifest/pod-targets.v1.json +1 -1
- package/manifest/routing.v1.json +3 -2
- package/manifest/targets.v1.json +1 -1
- package/package.json +1 -1
- package/protocol.json +3 -1
- package/schema/group.v1.schema.json +474 -0
- package/schema/interaction-flow-app.v1.schema.json +7 -3
package/README.md
CHANGED
|
@@ -17,6 +17,9 @@ owns public targets, request/response/event schemas, and stable operation
|
|
|
17
17
|
identity. Core-to-Node routes and provider runtime models belong to
|
|
18
18
|
`mhome-core-api` instead.
|
|
19
19
|
|
|
20
|
+
See [resource definition, observation, history and relationship reads](contract/resource-read-v1.md)
|
|
21
|
+
for shared business reads and the separate UI rendering boundary.
|
|
22
|
+
|
|
20
23
|
## Business DTO ownership
|
|
21
24
|
|
|
22
25
|
A Facade owns the public business DTO for an operation. Native Agent tools, MCP,
|
|
@@ -73,8 +76,15 @@ execution or replay. Reject returns cancellation. Response detail never changes
|
|
|
73
76
|
approval meaning or permission checks. Operation and HITL continuation protocols
|
|
74
77
|
are separate from this result envelope.
|
|
75
78
|
|
|
76
|
-
App UI requests full and
|
|
77
|
-
|
|
79
|
+
App UI requests full and preserves the complete envelope through transport and SDK
|
|
80
|
+
parsing. UI consumers explicitly read data and handle warnings and non-success outcomes.
|
|
81
|
+
Essential YAML omits null-valued object fields recursively after domain projection.
|
|
82
|
+
This shared rule also applies to error diagnostics and visible warning details.
|
|
83
|
+
Full values, false, zero, strings (including empty strings), empty collections,
|
|
84
|
+
array positions and a root null value are preserved. This is output-only; it
|
|
85
|
+
never changes request semantics, stored data or prepared actions.
|
|
86
|
+
|
|
87
|
+
Agent and MCP public results use essential; internal workflow reads use full. The CLI
|
|
78
88
|
uses `--response-detail full|essential`, and the bundled external Skill requests
|
|
79
89
|
essential. Dashboard essential projection keeps card identity, title, type,
|
|
80
90
|
view choices, excluding renderer configuration and resource payloads. Card list
|
|
@@ -134,6 +144,15 @@ its complete referenced value is available and which visible inputs can make
|
|
|
134
144
|
it stale, so clients can resolve it reactively without learning handlers or
|
|
135
145
|
the hidden graph.
|
|
136
146
|
|
|
147
|
+
Final completion can return `completed: false` with `submission.status: accepted`:
|
|
148
|
+
the business owner has saved the input but installation has not finished. Clients
|
|
149
|
+
retain the completion command ID and may query `/app/interaction-flow/submission/status`
|
|
150
|
+
or explicitly call `/app/interaction-flow/submission/retry` with the original source
|
|
151
|
+
and that ID. Neither call requires a live interactive session. Responses distinguish
|
|
152
|
+
`notFound`, `accepted`, and `completed` with the original result. Clients cannot
|
|
153
|
+
supply an owner or handler; current Node binding and Space access are checked again.
|
|
154
|
+
Retry is explicit, and closing the interaction does not cancel accepted business data.
|
|
155
|
+
|
|
137
156
|
`topology` exposes the Hub-owned Space network projection. Stable Host, Hub,
|
|
138
157
|
Node, AppClient, and Cloud identities are separate from current transport
|
|
139
158
|
sessions. Durable relations remain present while disconnected and carry an
|
|
@@ -225,3 +244,17 @@ Business operation permissions are declared once in [the authorization manifest]
|
|
|
225
244
|
|
|
226
245
|
UI Integration metadata uses `/app/integration/presentation/get`; see
|
|
227
246
|
[the presentation contract](contract/integration-presentation-v1.md).
|
|
247
|
+
|
|
248
|
+
## Artifact delivery
|
|
249
|
+
|
|
250
|
+
`/app/artifact/resolve` follows the Space execution route and can return a Host-local
|
|
251
|
+
URL with its TLS identity. `/app/artifact/external/resolve` is an explicit cloud-only
|
|
252
|
+
read using the same `ResolveArtifactRequest` and `ResolveArtifactResponse` contract.
|
|
253
|
+
It returns a short-lived signed HTTPS URL through an externally reachable cloud
|
|
254
|
+
origin. Its deadline is capped by the artifact's expiry at issuance. Issuing a URL
|
|
255
|
+
does not renew retention; reading local temporary content retains the owner's
|
|
256
|
+
normal idle-renewal behavior without extending an already issued URL's deadline.
|
|
257
|
+
Cloud-owned content uses an object-store signed URL; local content is read from its
|
|
258
|
+
owning Hub on demand. External resolution creates no cloud replica and cannot
|
|
259
|
+
make an offline local owner readable. The current inline Hub bridge size limit
|
|
260
|
+
still applies. Local file download remains a client workflow over ordinary resolve.
|
|
@@ -18,5 +18,5 @@ are performed. Current Twin states still have their separate read/subscription.
|
|
|
18
18
|
|
|
19
19
|
UI uses `control: {mode: "direct", responseDetail: "full"}` and receives the shared
|
|
20
20
|
`{status: "success", data: ...}` envelope. The generic essential projection returns
|
|
21
|
-
`{status: "success",
|
|
21
|
+
`{status: "success", data: ...}` with the same business fields rendered as YAML;
|
|
22
22
|
there is no domain field reduction. This is not the compact business detail API.
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Resource read boundaries
|
|
2
|
+
|
|
3
|
+
Business reads separate persisted definitions/configuration from current observations,
|
|
4
|
+
chronological history, and one-hop resource relationships. Tenant and Space are taken
|
|
5
|
+
from authenticated request context. All targets require Space read authority and
|
|
6
|
+
follow the Space execution authority on both local Core and cloud.
|
|
7
|
+
|
|
8
|
+
## Shared business reads
|
|
9
|
+
|
|
10
|
+
| Target | Input | Business data |
|
|
11
|
+
| --- | --- | --- |
|
|
12
|
+
| `/app/device/detail/get` | `{ids}` | Existing ordered `items` with `device` definitions, capabilities, group membership, enabled/source metadata; no online or state fields |
|
|
13
|
+
| `/app/device/state/get` | `{ids}` | Ordered `items` with `resource: {entityId, online?, onlineUpdatedAtSec?, latest}` |
|
|
14
|
+
| `/app/widget/detail/get` | `{ids}` | Existing ordered `items` with `widget` configuration; no value, next or nextTimestamp |
|
|
15
|
+
| `/app/widget/value/get` | `{ids}` | Ordered `items` with `resource: {widgetId, revision, value, next?, nextTimestamp?}` |
|
|
16
|
+
| `/app/automation/status` | `{ids}` | Ordered `items` with `resource: {automationId, enabled, runnable, running, blocked, lastRunAt}` |
|
|
17
|
+
| `/app/graph/relations/get` | `{resource: {kind, id}}` | `{resource, relations: [{from, relation, to, capabilityIds?}]}` |
|
|
18
|
+
|
|
19
|
+
Observation batches accept 1–100 IDs, reject blanks, trim and deduplicate preserving
|
|
20
|
+
request order. Every normalized ID gets `{requestedId, found, resource?}`; missing
|
|
21
|
+
resources have `found: false, reason: "not_found"`. A known Device with no observations
|
|
22
|
+
has `found: true` and `latest: []`. Unknown reachability omits `online`; it is not false.
|
|
23
|
+
Device state supports visible physical devices and Device groups. Automation status
|
|
24
|
+
accepts user program IDs, including retained one-time programs, not groups or internal
|
|
25
|
+
Twin programs. Widget value supports Data, Button and Circadian resources. JSON null
|
|
26
|
+
is a value, not a missing resource. Button values may be null.
|
|
27
|
+
|
|
28
|
+
`latest` contains one record per capability: `capabilityId`, optional `state`, `event`,
|
|
29
|
+
`log`. These preserve the decoded Twin observation objects and their second timestamps.
|
|
30
|
+
They contain no persistence tenant/Space keys. Reads use stored latest snapshots and
|
|
31
|
+
retain the existing history fallback on cache miss; they do not refresh providers.
|
|
32
|
+
Definition reads do not load observations, history, related programs or visible Cards.
|
|
33
|
+
|
|
34
|
+
Graph kinds are `device`, `entity`, `automation`, `widget`, `card`. Directional relations
|
|
35
|
+
are Automation `uses` Device/Entity (with capability IDs), Automation `owns` Widget,
|
|
36
|
+
visible Card `presents` a resource, and generated Automation `implements` Device.
|
|
37
|
+
Generated program references are not editable user programs. Existing Managers and
|
|
38
|
+
indexes own these relationships; this read introduces no graph database or traversal.
|
|
39
|
+
It returns IDs, not recursively expanded definitions, scripts, names or runtime data.
|
|
40
|
+
Hidden Device render anchors are not public Card references.
|
|
41
|
+
|
|
42
|
+
Full uses the standard `{status, data}` result with structured business data. Essential
|
|
43
|
+
uses the same envelope with YAML `data`; timestamps are presented in the Home timezone.
|
|
44
|
+
Device list additionally omits connection/manufacturer metadata in Essential. New
|
|
45
|
+
observation and graph reads preserve their bounded business fields in Essential.
|
|
46
|
+
|
|
47
|
+
## UI-only reads
|
|
48
|
+
|
|
49
|
+
- `/app/device/view/get`, `{deviceId}`: `{deviceId, primaryViewId, views, widgets}`.
|
|
50
|
+
Reads the unique hidden Device render definition, preserving exact Widget/Twin
|
|
51
|
+
bindings. Disabled devices can have empty definitions. Multiple anchors fail rather
|
|
52
|
+
than choosing an arbitrary visible Card. Widgets contain configuration, never values.
|
|
53
|
+
- `/app/device/history/series/get`, `{deviceId, capabilityIds?: []}`:
|
|
54
|
+
`{deviceId, series}` with per-capability decoded `states`, `events`, `logs`. Empty
|
|
55
|
+
capability selection reads all series. This preserves chart structure; the shared
|
|
56
|
+
Device history Facade remains a bounded, merged business timeline.
|
|
57
|
+
- `/app/dashboard/canvas/content/get`, `{canvasId}`: Canvas metadata plus Cards' static
|
|
58
|
+
titles, view bindings, layouts, settings, metadata and selected Widget definitions.
|
|
59
|
+
No observations, history, related automations or suggestions are loaded.
|
|
60
|
+
|
|
61
|
+
The frontend batches selected observations after reading definitions. Automation Cards
|
|
62
|
+
also read selected Automation definitions for their name and type. Canvas IDs are
|
|
63
|
+
split into bounded batches and deduplicated across Cards. History is requested by an
|
|
64
|
+
open detail renderer; relationships by the view that displays them. Pushes received
|
|
65
|
+
during a snapshot request are applied after it lands. Switching scopes or disposing
|
|
66
|
+
controllers prevents late responses from landing in another Space.
|
|
67
|
+
|
|
68
|
+
House continues to use `/app/entity/presentation/get` and legacy Twin reads as its
|
|
69
|
+
separate development boundary. Pod Deck retains its existing complete Card content
|
|
70
|
+
reader. These consumers are not silently migrated to static Canvas responses.
|
|
71
|
+
|
|
72
|
+
Generated Twin program inspection retains its internal `/automation/get`,
|
|
73
|
+
`/automation/status` and `/automation/info` UI readers. These IDs are not accepted
|
|
74
|
+
by the shared user-program Automation detail/status contract. User program detail
|
|
75
|
+
pages use the shared definition, status and graph readers.
|
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
{
|
|
2
|
+
"valid": [
|
|
3
|
+
{
|
|
4
|
+
"definition": "ListGroupsInput",
|
|
5
|
+
"value": {}
|
|
6
|
+
},
|
|
7
|
+
{
|
|
8
|
+
"definition": "GetGroupsInput",
|
|
9
|
+
"value": {
|
|
10
|
+
"ids": [
|
|
11
|
+
"g:1",
|
|
12
|
+
"g:1",
|
|
13
|
+
"missing"
|
|
14
|
+
]
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"definition": "GroupPresentationInput",
|
|
19
|
+
"value": {
|
|
20
|
+
"groupId": "g:1"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"definition": "CreateGroupInput",
|
|
25
|
+
"value": {
|
|
26
|
+
"creationId": "11111111-1111-4111-8111-111111111111",
|
|
27
|
+
"name": "Lights",
|
|
28
|
+
"memberType": "basic.device.Device",
|
|
29
|
+
"memberIds": [
|
|
30
|
+
"lamp-a",
|
|
31
|
+
"lamp-b",
|
|
32
|
+
"lamp-a"
|
|
33
|
+
]
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"definition": "RenameGroupInput",
|
|
38
|
+
"value": {
|
|
39
|
+
"groupId": "g:1",
|
|
40
|
+
"name": "Renamed",
|
|
41
|
+
"expectedRevision": 3
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"definition": "UpdateGroupMembersInput",
|
|
46
|
+
"value": {
|
|
47
|
+
"groupId": "g:1",
|
|
48
|
+
"memberIds": [
|
|
49
|
+
"lamp-b"
|
|
50
|
+
],
|
|
51
|
+
"expectedRevision": 3
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"definition": "DeleteGroupInput",
|
|
56
|
+
"value": {
|
|
57
|
+
"groupId": "g:1",
|
|
58
|
+
"expectedRevision": 3
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"definition": "GroupSummary",
|
|
63
|
+
"value": {
|
|
64
|
+
"groupId": "g:11111111-1111-4111-8111-111111111111",
|
|
65
|
+
"name": "Lights",
|
|
66
|
+
"memberType": "basic.device.Device",
|
|
67
|
+
"memberCount": 2,
|
|
68
|
+
"revision": 3,
|
|
69
|
+
"applyState": "ready",
|
|
70
|
+
"createdAt": 1900000000000,
|
|
71
|
+
"updatedAt": 1900000001000
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"definition": "GroupDetail",
|
|
76
|
+
"value": {
|
|
77
|
+
"groupId": "g:11111111-1111-4111-8111-111111111111",
|
|
78
|
+
"name": "Lights",
|
|
79
|
+
"memberType": "basic.device.Device",
|
|
80
|
+
"memberCount": 2,
|
|
81
|
+
"revision": 3,
|
|
82
|
+
"applyState": "ready",
|
|
83
|
+
"createdAt": 1900000000000,
|
|
84
|
+
"updatedAt": 1900000001000,
|
|
85
|
+
"memberIds": [
|
|
86
|
+
"lamp-a",
|
|
87
|
+
"lamp-b"
|
|
88
|
+
],
|
|
89
|
+
"capabilities": [
|
|
90
|
+
{
|
|
91
|
+
"id": "basic.device.command.onOff",
|
|
92
|
+
"memberCount": 1
|
|
93
|
+
}
|
|
94
|
+
],
|
|
95
|
+
"memberProblems": [
|
|
96
|
+
{
|
|
97
|
+
"memberId": "lamp-b",
|
|
98
|
+
"code": "MEMBER_UNAVAILABLE",
|
|
99
|
+
"message": "Member is unavailable"
|
|
100
|
+
}
|
|
101
|
+
]
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"definition": "GroupMutationOutput",
|
|
106
|
+
"value": {
|
|
107
|
+
"groupId": "g:1",
|
|
108
|
+
"revision": 4,
|
|
109
|
+
"applyState": "failed",
|
|
110
|
+
"applicationProblem": {
|
|
111
|
+
"code": "GROUP_APPLY_FAILED",
|
|
112
|
+
"message": "Retry application"
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"definition": "DeleteGroupOutput",
|
|
118
|
+
"value": {
|
|
119
|
+
"groupId": "g:1",
|
|
120
|
+
"deleted": true
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
"definition": "ListGroupsOutput",
|
|
125
|
+
"value": {
|
|
126
|
+
"spaceId": "space",
|
|
127
|
+
"groups": [
|
|
128
|
+
{
|
|
129
|
+
"groupId": "g:11111111-1111-4111-8111-111111111111",
|
|
130
|
+
"name": "Lights",
|
|
131
|
+
"memberType": "basic.device.Device",
|
|
132
|
+
"memberCount": 2,
|
|
133
|
+
"revision": 3,
|
|
134
|
+
"applyState": "ready",
|
|
135
|
+
"createdAt": 1900000000000,
|
|
136
|
+
"updatedAt": 1900000001000
|
|
137
|
+
}
|
|
138
|
+
]
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
"definition": "GetGroupsOutput",
|
|
143
|
+
"value": {
|
|
144
|
+
"spaceId": "space",
|
|
145
|
+
"items": [
|
|
146
|
+
{
|
|
147
|
+
"requestedId": "g:11111111-1111-4111-8111-111111111111",
|
|
148
|
+
"found": true,
|
|
149
|
+
"group": {
|
|
150
|
+
"groupId": "g:11111111-1111-4111-8111-111111111111",
|
|
151
|
+
"name": "Lights",
|
|
152
|
+
"memberType": "basic.device.Device",
|
|
153
|
+
"memberCount": 2,
|
|
154
|
+
"revision": 3,
|
|
155
|
+
"applyState": "ready",
|
|
156
|
+
"createdAt": 1900000000000,
|
|
157
|
+
"updatedAt": 1900000001000,
|
|
158
|
+
"memberIds": [
|
|
159
|
+
"lamp-a",
|
|
160
|
+
"lamp-b"
|
|
161
|
+
],
|
|
162
|
+
"capabilities": [
|
|
163
|
+
{
|
|
164
|
+
"id": "basic.device.command.onOff",
|
|
165
|
+
"memberCount": 1
|
|
166
|
+
}
|
|
167
|
+
],
|
|
168
|
+
"memberProblems": [
|
|
169
|
+
{
|
|
170
|
+
"memberId": "lamp-b",
|
|
171
|
+
"code": "MEMBER_UNAVAILABLE",
|
|
172
|
+
"message": "Member is unavailable"
|
|
173
|
+
}
|
|
174
|
+
]
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
"requestedId": "missing",
|
|
179
|
+
"found": false,
|
|
180
|
+
"reason": "not_found"
|
|
181
|
+
}
|
|
182
|
+
]
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
],
|
|
186
|
+
"invalid": [
|
|
187
|
+
{
|
|
188
|
+
"definition": "RenameGroupInput",
|
|
189
|
+
"value": {
|
|
190
|
+
"groupId": "g:1",
|
|
191
|
+
"name": "Renamed"
|
|
192
|
+
}
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
"definition": "UpdateGroupMembersInput",
|
|
196
|
+
"value": {
|
|
197
|
+
"groupId": "g:1",
|
|
198
|
+
"memberIds": [
|
|
199
|
+
"lamp-b"
|
|
200
|
+
],
|
|
201
|
+
"expectedRevision": 3,
|
|
202
|
+
"name": "Unexpected"
|
|
203
|
+
}
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
"definition": "DeleteGroupInput",
|
|
207
|
+
"value": {
|
|
208
|
+
"groupId": "g:1",
|
|
209
|
+
"expectedRevision": 0
|
|
210
|
+
}
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
"definition": "CreateGroupInput",
|
|
214
|
+
"value": {
|
|
215
|
+
"creationId": "11111111-1111-4111-8111-111111111111",
|
|
216
|
+
"name": "Lights",
|
|
217
|
+
"memberType": "basic.device.Device",
|
|
218
|
+
"memberIds": [
|
|
219
|
+
"lamp-a",
|
|
220
|
+
"lamp-b",
|
|
221
|
+
"lamp-a"
|
|
222
|
+
],
|
|
223
|
+
"members": [
|
|
224
|
+
{
|
|
225
|
+
"data": "internal"
|
|
226
|
+
}
|
|
227
|
+
]
|
|
228
|
+
}
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
"definition": "GroupDetail",
|
|
232
|
+
"value": {
|
|
233
|
+
"groupId": "g:11111111-1111-4111-8111-111111111111",
|
|
234
|
+
"name": "Lights",
|
|
235
|
+
"memberType": "basic.device.Device",
|
|
236
|
+
"memberCount": 2,
|
|
237
|
+
"revision": 3,
|
|
238
|
+
"applyState": "ready",
|
|
239
|
+
"createdAt": 1900000000000,
|
|
240
|
+
"updatedAt": 1900000001000,
|
|
241
|
+
"memberIds": [
|
|
242
|
+
"lamp-a",
|
|
243
|
+
"lamp-b"
|
|
244
|
+
],
|
|
245
|
+
"capabilities": [
|
|
246
|
+
{
|
|
247
|
+
"id": "basic.device.command.onOff",
|
|
248
|
+
"memberCount": 1
|
|
249
|
+
}
|
|
250
|
+
],
|
|
251
|
+
"memberProblems": [
|
|
252
|
+
{
|
|
253
|
+
"memberId": "lamp-b",
|
|
254
|
+
"code": "MEMBER_UNAVAILABLE",
|
|
255
|
+
"message": "Member is unavailable"
|
|
256
|
+
}
|
|
257
|
+
],
|
|
258
|
+
"twinSig": "internal"
|
|
259
|
+
}
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
"definition": "GetGroupsInput",
|
|
263
|
+
"value": {
|
|
264
|
+
"ids": [
|
|
265
|
+
"a",
|
|
266
|
+
"a",
|
|
267
|
+
"a",
|
|
268
|
+
"a",
|
|
269
|
+
"a",
|
|
270
|
+
"a",
|
|
271
|
+
"a",
|
|
272
|
+
"a",
|
|
273
|
+
"a",
|
|
274
|
+
"a",
|
|
275
|
+
"a",
|
|
276
|
+
"a",
|
|
277
|
+
"a",
|
|
278
|
+
"a",
|
|
279
|
+
"a",
|
|
280
|
+
"a",
|
|
281
|
+
"a",
|
|
282
|
+
"a",
|
|
283
|
+
"a",
|
|
284
|
+
"a",
|
|
285
|
+
"a",
|
|
286
|
+
"a",
|
|
287
|
+
"a",
|
|
288
|
+
"a",
|
|
289
|
+
"a",
|
|
290
|
+
"a",
|
|
291
|
+
"a",
|
|
292
|
+
"a",
|
|
293
|
+
"a",
|
|
294
|
+
"a",
|
|
295
|
+
"a",
|
|
296
|
+
"a",
|
|
297
|
+
"a",
|
|
298
|
+
"a",
|
|
299
|
+
"a",
|
|
300
|
+
"a",
|
|
301
|
+
"a",
|
|
302
|
+
"a",
|
|
303
|
+
"a",
|
|
304
|
+
"a",
|
|
305
|
+
"a",
|
|
306
|
+
"a",
|
|
307
|
+
"a",
|
|
308
|
+
"a",
|
|
309
|
+
"a",
|
|
310
|
+
"a",
|
|
311
|
+
"a",
|
|
312
|
+
"a",
|
|
313
|
+
"a",
|
|
314
|
+
"a",
|
|
315
|
+
"a",
|
|
316
|
+
"a",
|
|
317
|
+
"a",
|
|
318
|
+
"a",
|
|
319
|
+
"a",
|
|
320
|
+
"a",
|
|
321
|
+
"a",
|
|
322
|
+
"a",
|
|
323
|
+
"a",
|
|
324
|
+
"a",
|
|
325
|
+
"a",
|
|
326
|
+
"a",
|
|
327
|
+
"a",
|
|
328
|
+
"a",
|
|
329
|
+
"a",
|
|
330
|
+
"a",
|
|
331
|
+
"a",
|
|
332
|
+
"a",
|
|
333
|
+
"a",
|
|
334
|
+
"a",
|
|
335
|
+
"a",
|
|
336
|
+
"a",
|
|
337
|
+
"a",
|
|
338
|
+
"a",
|
|
339
|
+
"a",
|
|
340
|
+
"a",
|
|
341
|
+
"a",
|
|
342
|
+
"a",
|
|
343
|
+
"a",
|
|
344
|
+
"a",
|
|
345
|
+
"a",
|
|
346
|
+
"a",
|
|
347
|
+
"a",
|
|
348
|
+
"a",
|
|
349
|
+
"a",
|
|
350
|
+
"a",
|
|
351
|
+
"a",
|
|
352
|
+
"a",
|
|
353
|
+
"a",
|
|
354
|
+
"a",
|
|
355
|
+
"a",
|
|
356
|
+
"a",
|
|
357
|
+
"a",
|
|
358
|
+
"a",
|
|
359
|
+
"a",
|
|
360
|
+
"a",
|
|
361
|
+
"a",
|
|
362
|
+
"a",
|
|
363
|
+
"a",
|
|
364
|
+
"a",
|
|
365
|
+
"a"
|
|
366
|
+
]
|
|
367
|
+
}
|
|
368
|
+
},
|
|
369
|
+
{
|
|
370
|
+
"definition": "GroupSummary",
|
|
371
|
+
"value": {
|
|
372
|
+
"groupId": "g:11111111-1111-4111-8111-111111111111",
|
|
373
|
+
"name": "Lights",
|
|
374
|
+
"memberType": "basic.device.Device",
|
|
375
|
+
"memberCount": 2,
|
|
376
|
+
"revision": 3,
|
|
377
|
+
"applyState": "unknown",
|
|
378
|
+
"createdAt": 1900000000000,
|
|
379
|
+
"updatedAt": 1900000001000
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
]
|
|
383
|
+
}
|
|
@@ -70,9 +70,28 @@
|
|
|
70
70
|
"completed": true,
|
|
71
71
|
"result": {
|
|
72
72
|
"providerConnectionId": "provider-1"
|
|
73
|
+
},
|
|
74
|
+
"submission": {
|
|
75
|
+
"status": "completed",
|
|
76
|
+
"result": {
|
|
77
|
+
"providerConnectionId": "provider-1"
|
|
78
|
+
}
|
|
73
79
|
}
|
|
74
80
|
},
|
|
75
81
|
"cancelResponse": {
|
|
76
82
|
"cancelled": true
|
|
83
|
+
},
|
|
84
|
+
"submissionRequest": {
|
|
85
|
+
"source": {
|
|
86
|
+
"kind": "plugin",
|
|
87
|
+
"nodeType": "camera",
|
|
88
|
+
"nodeId": "camera-1",
|
|
89
|
+
"flowId": "provider.connect",
|
|
90
|
+
"subjectId": "onvif"
|
|
91
|
+
},
|
|
92
|
+
"submissionId": "command-3"
|
|
93
|
+
},
|
|
94
|
+
"submissionResponse": {
|
|
95
|
+
"status": "accepted"
|
|
77
96
|
}
|
|
78
97
|
}
|