Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

writeProperty message #38

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
77 changes: 72 additions & 5 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,12 @@ <h2>WebSocket Messages</h2>
<td>PropertyAffordance</td>
<td>Consumer ➡ Thing</td>
</tr>
<tr>
<td><a href="#writeProperty"><code>writeProperty</code></a></td>
<td>Set the value of a property</td>
<td>PropertyAffordance</td>
<td>Consumer ➡ Thing</td>
</tr>
<tr>
<td><a href="#propertyReading"><code>propertyReading</code></a></td>
<td>A property reading from a Thing</td>
Expand Down Expand Up @@ -347,7 +353,7 @@ <h4><code>readProperty</code></h4>
</tr>
</tbody>
</table>
<pre class="example" title="Read property operation (Consumer to Thing)">
<pre class="example" title="Read property message (Consumer to Thing)">
{
"thingID": "https://mythingserver.com/things/mylamp1",
"messageID": "c370da58-69ae-4e83-bb5a-ac6cfb2fed54",
Expand All @@ -361,6 +367,67 @@ <h4><code>readProperty</code></h4>
href="propertyReading"><code>propertyReading</code></a> message in response, containing its current value.
</p>
</section>

<section id="writeProperty">
<h4><code>writeProperty</code></h4>
<p>To set the value of a <a>Property</a> of a <a>Thing</a>, a <a>Consumer</a> MUST send a <a
href="#websocket-messages">message</a> to the <a>Thing</a> which contains the following members:</p>
<table class="def">
<caption>Members of a <code>writeProperty</code> message</caption>
<thead>
<tr>
<th>Member</th>
<th>Type</th>
<th>Assignment</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>messageType</code></td>
<td>string</td>
<td>"writeProperty"</td>
<td>A string which denotes that this message is requesting a <code>writeproperty</code> operation.</td>
</tr>
<tr>
<td><code>name</code></td>
<td>string</td>
<td>Mandatory</td>
<td>The name of the <a>Property</a> whose value should be set, as per its key in the
<code>properties</code> member of the <a>Thing Description</a>.
</td>
</tr>
<tr>
<td><code>value</code></td>
<td>any</td>
<td>Mandatory</td>
<td>The desired new value of the <a>Property</a>, with a format conforming to the data schema of the
corresponding PropertyAffordance in the <a>Thing Description</a>.</td>
</tr>
</tbody>
</table>
<pre class="example" title="Write property message (Consumer to Thing)">
{
"thingID": "https://mythingserver.com/things/mylamp1",
"messageID": "adbefb2c-9c10-4a9e-b2d5-840a58ab667e",
"messageType": "writeProperty",
"name": "on",
"value": true,
"correlationID": "b737e900-2b34-4315-bf9e-9eec1a0406c0"
}
</pre>
<p>When a <a>Thing</a> receives a <code>writeProperty</code> message from a <a>Consumer</a>, then upon
successfully writing the value of the corresponding <a>Property</a> it SHOULD send a <a
href="propertyReading"><code>propertyReading</code></a> message in response, containing its updated value.
</p>
<p class="note" title="Write-only Properties">In some cases it may not be possible for an underlying
implementation to confirm that a value has been written. The <code>writeOnly</code> member of a
PropertyAffordance being set to <code>true</code> may hint that this is the case. For this reason, a
Copy link
Collaborator

Choose a reason for hiding this comment

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

To me these are two different things. Write-only means that the value of the property cannot be read. The ability to confirm that a write was completed is a separate concern.
If the underlying hardware offers no such confirmation then a 'completed' response would mean that the write was applied. I would still like to see a confirmation.

Copy link
Member Author

Choose a reason for hiding this comment

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

I agree that a property that can't be read and a write that can't be confirmed could be argued to be subtly different things. However, unconfirmable writes do exist.

For example, in the X10 communication protocol some devices do not acknowledge the receipt of commands. You can send a command to switch a device on, but there's no way to tell whether that command was received.

My concern would be that if a Web Thing sends a confirmation message when a write may not actually have been completed or received, it may be misleading.

As far as I know a Thing Description has no way to distinguish a confirmable writeproperty operation from a non-confirmable one (other than by using the writeOnly member of a PropertyAffordance).

Therefore my suggestion would be that a Web Thing that can not confirm whether a write operation has succeeded (for whatever reason) should use the writeOnly member as a hint, and a Consumer should not treat a lack of a response as an error condition in that case. An error message could be sent in response if the write is definitely known to have failed.

Copy link
Collaborator

@RobWin RobWin Feb 8, 2025

Choose a reason for hiding this comment

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

That's why I would really like to differentiate between propertyReading and an acknowledgment that the write request or invokeAction request was processed using the best available method. Even if a write operation cannot be confirmed, the Thing provider should still be able to acknowledge that the request was received and acted upon to the best of its ability.

Copy link
Member Author

Choose a reason for hiding this comment

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

If there's a need for a message type to acknowledge a propertyWrite message without providing a property reading, then yes it does seem like that would need to be separate message type from propertyReading. Adding a special "propertyWriteAcknowledgement" message type feels wrong though, so if this really is important then maybe this is further evidence for the need to split out operation name and message type.

I've filed #42 to explore this further.

Copy link
Member

Choose a reason for hiding this comment

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

I read through the proposal and I also find this point very sensitive. My main concern his how a Consumer should behave when writing a property. If the response "acknowledge" (either we decide to use propertyReading or dedicated ack) MIGHT arrive, then the best behaviour is to never wait for something, but rather request again a property read (if not write-only). If we don't have the ability to specify if a property write is acknowledgable by the TD, I think the default should be "there is no acknowledge".

I would explore the possibility to introduce the term acknowledge: true as a custom protocol binding keyword.

Copy link
Collaborator

Choose a reason for hiding this comment

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

My vote goes to Ben's proposal in #42:

Response
{
  "thingID": "https://mythingserver.com/things/mylamp1",
  "messageID": "79057736-3e0e-4dc3-b139-a33051901ee2",
  "messageType": "response",
  "operation": "writeproperty",
  "name": "on",
  "value": true,
  "correlationID": "5afb752f-8be0-4a3c-8108-1327a6009cbd"
}
Note: To address the issue raised in https://github.com/w3c/web-thing-protocol/pull/38 about non-confirmable writes, a value could only be provided in a response if it is confirmed to have been written.

This addresses the concern I raised as there is always a response. The response can carry a value if the output is available, no value if the property is writeonly, or an error if it fails. This is deterministic and simple. The Affordance already states whether the property is writeonly so there is no guesswork involved.

Copy link
Member

Choose a reason for hiding this comment

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

Sorry I didn't catch up with the discussion. Then I definitely support the direction above!

<a>Consumer</a> should not necessarily assume that a <code>writeproperty</code> operation is unsuccessful if
no <code>propertyReading</code> message is received in response.
</p>
</section>

<section id="propertyReading">
<h4><code>propertyReading</code></h4>
<p>To notify a <a>Consumer</a> of the value of a <a>Property</a>, a <a>Thing</a> MUST send a
Expand Down Expand Up @@ -411,10 +478,10 @@ <h4><code>propertyReading</code></h4>
</tbody>
</table>
<p>If a <code>propertyReading</code> message is sent in response to a <a
href="#readProperty"><code>readProperty</code></a>, <code>readAllProperties</code>,
<code>observeProperty</code> or <code>observeAllProperties</code> message which contained a
<code>correlatonID</code> member, then the response message SHOULD also include a <code>correlationID</code>
member with the same value.
href="#readProperty"><code>readProperty</code></a>, <a href="#writeProperty"><code>writeProperty</code></a>,
<code>readAllProperties</code>, <code>observeProperty</code> or <code>observeAllProperties</code> message
which contained a <code>correlatonID</code> member, then the response message SHOULD also include a
<code>correlationID</code> member with the same value.
</p>
<pre class="example" title="Property reading message (Thing to Consumer)">
{
Expand Down