From 050a30f72ccaad2d0468ab693f89729ca9f562fe Mon Sep 17 00:00:00 2001 From: HomeSpan Date: Sun, 21 Apr 2024 21:16:08 -0500 Subject: [PATCH 1/4] Update Reference.md --- docs/Reference.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/Reference.md b/docs/Reference.md index 93ea7b7..0ec35cf 100644 --- a/docs/Reference.md +++ b/docs/Reference.md @@ -627,8 +627,9 @@ To create more than one user-defined command, simply create multiple instances o ### *CUSTOM_CHAR(name,uuid,perms,format,defaultValue,minValue,maxValue,staticRange)* ### *CUSTOM_CHAR_STRING(name,uuid,perms,defaultValue)* ### *CUSTOM_CHAR_DATA(name,uuid,perms)* +### *CUSTOM_CHAR_TLV8(name,uuid,perms)* -Creates a custom Characteristic that can be added to any Service. Custom Characteristics are generally ignored by the Home App but may be used by other third-party applications (such as *Eve for HomeKit*). The first form should be used create numerical Characterstics (e.g., UINT8, BOOL...). The second form is used to STRING-based Characteristics. The third form is used for DATA-based (i.e. byte-array) Characteristics. Parameters are as follows (note that quotes should NOT be used in any of the macro parameters, except for *defaultValue* when applied to a STRING-based Characteristic): +Creates a custom Characteristic that can be added to any Service. Custom Characteristics are generally ignored by the Home App but may be used by other third-party applications (such as *Eve for HomeKit*). The first form should be used create numerical Characterstics (e.g., UINT8, BOOL...); the second form is used to STRING-based Characteristics; the third form is used for DATA-based (i.e. byte-array) Characteristics; and the fourth form is used for TLV8-based (i.e. *structured* byte-array) Characteristics Parameters are as follows (note that quotes should NOT be used in any of the macro parameters, except for *defaultValue* when applied to a STRING-based Characteristic): * *name* - the name of the custom Characteristic. This will be added to the Characteristic namespace so that it is accessed the same as any HomeSpan Characteristic. Use UTF-8 coded string for non-ASCII characters. * *uuid* - the UUID of the Characteristic as defined by the manufacturer. Must be *exactly* 36 characters in the form XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX, where *X* represent a valid hexidecimal digit. Leading zeros are required if needed as described more fully in HAP-R2 Section 6.6.1 From 0be3b0cd1b4a768e9a110084b98c14b3769161e4 Mon Sep 17 00:00:00 2001 From: HomeSpan Date: Sun, 21 Apr 2024 21:23:44 -0500 Subject: [PATCH 2/4] Update Reference.md --- docs/Reference.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Reference.md b/docs/Reference.md index 0ec35cf..1bf1bb2 100644 --- a/docs/Reference.md +++ b/docs/Reference.md @@ -478,7 +478,7 @@ This is a **base class** from which all HomeSpan Characteristics are derived, an * similar to `setVal()`, but exclusively used for TLV8 Characteristics * updates the Characteristic by packing the TLV8 structure *tlv* into a byte array and then encoding it in base-64 for storage as a string -* see the [TLV8 Characteristics](TLV8.md) page for complete details on how to read/process/create TLV8 Characteristics +* see the [TLV8 Characteristics](TLV8.md) page for complete details on how to read/process/create TLV8 Objects using HomeSpan's TLV8 Library. #### The following methods are supported for all Characteristics: From c7f67225d6276c96dcf03b04c6f46ef476dd9f7f Mon Sep 17 00:00:00 2001 From: HomeSpan Date: Sun, 21 Apr 2024 22:08:04 -0500 Subject: [PATCH 3/4] Update TLV8.md --- docs/TLV8.md | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/docs/TLV8.md b/docs/TLV8.md index 3a9508a..de79755 100644 --- a/docs/TLV8.md +++ b/docs/TLV8.md @@ -274,17 +274,35 @@ it_E TAG=200, LENGTH=32, Sum of all bytes = 496 ## Reading and Writing TLV8 Characteristics -As documented in the [API Reference](Reference.md), the following *SpanCharacteristic* methods are used to read and write TLV8 objects to TLV8 Characteristics: +As fully documented in the [API Reference](Reference.md), the following *SpanCharacteristic* methods are used to read and write TLV8 objects to TLV8 Characteristics: -* `getVal(TLV8 &tlv)` -* `getNewVal(TLV8 &tlv)` -* `setVal(TLV8 &tlv)` +* `getTLV(TLV8 &tlv)` +* `getNewTLV(TLV8 &tlv)` +* `setTLV(TLV8 &tlv)` -These are analagous to the `getVal()` and `setVal()` methods used for numerical-based Characteristics. +These are analagous to the `getVal()`, `getNewVal()` and `setVal()` methods used for numerical-based Characteristics. -Note that since TLV8 Characteristics are stored as base-64 encoded strings, you can use `getString()` to read the base-64 text, or `getData()` to decode the string into the full byte-array that represents the entire TLV8 object. +Note that using the above methods *do not* require you to create a separate byte-array that splits records into chunks of 255 bytes, nor does it require you to encode or decode anything into base-64. Rather, you directly read and write to and from the Characteristic into a TLV8 object. -Also, if you really don't want to use HomeSpan's TLV8 library to produce TLV8 objects, but instead prefer to use your own methods to create a TLV8-compliant byte-array, you can do so and then use `setData()` to save the byte-array you produced to the TLV8 Characteristic, which will perform the base-64 encoding. Or if you want to additionally perform your own base-64 encoding (why?) you can do so and then simply use `setString()` to save the resulting encoded string to the TLV8 Characteristic. +However, since TLV8 Characteristics are stored as base-64 encoded strings, you can nevertheless use `getString()` to read the base-64 text, or `getData()` to decode the string into the full byte-array that represents the entire TLV8 object, if you desire. + +Also, if you really don't want to use HomeSpan's TLV8 library to produce TLV8 objects, but instead prefer to use your own methods to create a TLV8-compliant byte-array, you can do so and then use `setData()` to save the byte-array you produced to the TLV8 Characteristic, which will perform the base-64 encoding for you. Or, if you want to additionally perform your own base-64 encoding (why?), you can do so and then simply use `setString()` to save the resulting encoded text to the TLV8 Characteristic. + +### Write-Response Requests + +For most Characteristics, when the Home App sends HomeSpan a request to update a value, it is instructing HomeSpan to perform some sort of action, such as "change the brightness of a lightbulb to 30%" or "change the target state of the door to open." The only feedback the Home App expects to receive in response to such requests is basically an "OK" or "NOT OKAY" message, which is the purpose of the boolean return value in the `update()` method for every Service. + +However, sometimes the Home App sends HomeSpan a request for information, rather than a direct instruction to perform a task. In such instances, rather than sending back just an OK/NOT-OKAY message, the Home App expects the Accessory device to update the value of the Characteristic *not* with the new value that the Home App sent, but rather with the information it requested. It then expects this information to be transmitted back to the Home App at the conclusion of the update. + +This procedure is known as a "Write-Response Request", and it is the primary purpose for having TLV8 Characteristics, since TLV8 objects are ideal for storing structured information. + +Though the procedure is complex, HomeSpan fortunately handles all of the protocol details. The only thing you need to do when working with a TLV8 Characteristic that implements Write-Response Requests is: + +* check to see if the Characteristic is updated when inside the `update()` loop of a Service; +* if so, create a new TLV8 object and use `getNewTLV()` to load the contents of the updated Characterstic into that TLV8 object; +* use the TLV8 Library to read through the TAGS and VALUES in the TLV8 to determine (based on the specs for the Characteristic) what data the Home App is conveying and what information it wants returned; +* create a second TLV8 object and add the appropriate TAG and VALUES needed to respond to the information request (again, based on the on the specs for the Characteristic); +* use `setVal()` to update the Characteristic with the second TLV8 object --- From 20f74aa968f837d6f17a104a69c2796b8f1d013a Mon Sep 17 00:00:00 2001 From: HomeSpan Date: Mon, 22 Apr 2024 20:43:11 -0500 Subject: [PATCH 4/4] Update TLV8.md --- docs/TLV8.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/docs/TLV8.md b/docs/TLV8.md index de79755..85e853c 100644 --- a/docs/TLV8.md +++ b/docs/TLV8.md @@ -294,15 +294,17 @@ For most Characteristics, when the Home App sends HomeSpan a request to update a However, sometimes the Home App sends HomeSpan a request for information, rather than a direct instruction to perform a task. In such instances, rather than sending back just an OK/NOT-OKAY message, the Home App expects the Accessory device to update the value of the Characteristic *not* with the new value that the Home App sent, but rather with the information it requested. It then expects this information to be transmitted back to the Home App at the conclusion of the update. -This procedure is known as a "Write-Response Request", and it is the primary purpose for having TLV8 Characteristics, since TLV8 objects are ideal for storing structured information. +This procedure is known as a "Write-Response Request", and it is the primary purpose for having TLV8 Characteristics, since TLV8 objects are ideal for storing structured information. -Though the procedure is complex, HomeSpan fortunately handles all of the protocol details. The only thing you need to do when working with a TLV8 Characteristic that implements Write-Response Requests is: +Though the procedure is complex, HomeSpan handles all of the protocol details. You only need to focus on reading the TLV8 Characteristic and updating it with the required TLV8 response as follows: -* check to see if the Characteristic is updated when inside the `update()` loop of a Service; -* if so, create a new TLV8 object and use `getNewTLV()` to load the contents of the updated Characterstic into that TLV8 object; -* use the TLV8 Library to read through the TAGS and VALUES in the TLV8 to determine (based on the specs for the Characteristic) what data the Home App is conveying and what information it wants returned; -* create a second TLV8 object and add the appropriate TAG and VALUES needed to respond to the information request (again, based on the on the specs for the Characteristic); -* use `setVal()` to update the Characteristic with the second TLV8 object +* first, from within the `update()` loop of the applicable Service, check to see if the Home App has requested an update to the TLV8 Characteristic; +* if so, create a new TLV8 object and use `getNewTLV()` to load the contents of the updated Characteristic into that TLV8 object; +* then, use the TLV8 library methods described above to read through the TAGS and VALUES in the TLV8 object to determine what data the Home App is conveying and what information it wants returned (based on the specs for the Characteristic); +* next, create a *second* TLV8 object and use the TLV8 library methods above to create the appropriate TAGS and VALUES needed to respond to the information request (again, based on the on the specs for the Characteristic); +* finally, use `setVal()` to update the TLV8 Characteristic with the second TLV8 object + +HomeSpan will automatically send the new TLV8 data you placed in the TLV8 Characterstic back to the Home App in its response at the conclusion of the `update()` loop. ---