Completed Example 22-TLV8_Characteristics

Must update Television.md documentation as well as Television Example to reflect recent changes to the Characteristics Apple made - there seems to be less flexibility in what needs to be defined to use the input sources.

Also need to add DisplayOrder Characteristic to TV documentation.
This commit is contained in:
Gregg 2024-04-23 06:41:44 -05:00
parent a785c1f937
commit 3273f7f24d
1 changed files with 57 additions and 56 deletions

View File

@ -33,7 +33,7 @@
// Example 24: Demonstrates the use of the TLV8 Library // // Example 24: Demonstrates the use of the TLV8 Library //
// by implementing DisplayOrder, an optional // // by implementing DisplayOrder, an optional //
// TLV8 Characteristic used with the TV Service // // TLV8 Characteristic used with the TV Service //
// to sets the order in which TV Inputs are // // to set the order in which TV Inputs are //
// displayed for selection in the Home App // // displayed for selection in the Home App //
// // // //
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
@ -43,7 +43,7 @@
// NOTE: Please see the "Other Examples -> Television" sketch for complete details on how to implement a Television Service. The focus // NOTE: Please see the "Other Examples -> Television" sketch for complete details on how to implement a Television Service. The focus
// of this sketch is solely to demonstrate how to use the TLV8 Library to create TLV8 data for use with the DisplayOrder Characteristic. // of this sketch is solely to demonstrate how to use the TLV8 Library to create TLV8 data for use with the DisplayOrder Characteristic.
// First we define a simple Television Input Source Service with only the Identifer and Name Characteristics // First we define a simple Television Input Source Service
struct TVInput : Service::InputSource { struct TVInput : Service::InputSource {
@ -54,80 +54,81 @@ struct TVInput : Service::InputSource {
inputID = new Characteristic::Identifier(id); inputID = new Characteristic::Identifier(id);
inputName = new Characteristic::ConfiguredName(name); inputName = new Characteristic::ConfiguredName(name);
new Characteristic::IsConfigured(1); new Characteristic::IsConfigured(Characteristic::IsConfigured::CONFIGURED);
new Characteristic::CurrentVisibilityState(Characteristic::CurrentVisibilityState::VISIBLE);
} }
}; };
// Next we define a very simple Television Service // Next we define a simple Television Service
struct HomeSpanTV : Service::Television { struct HomeSpanTV : Service::Television {
SpanCharacteristic *active = new Characteristic::Active(0,true); // TV ON/OFF (set to OFF at start-up) SpanCharacteristic *active = new Characteristic::Active(0);
SpanCharacteristic *activeID = new Characteristic::ActiveIdentifier(30,true); // Set TV to input source with ID=30 SpanCharacteristic *activeID = new Characteristic::ActiveIdentifier(10);
// SpanCharacteristic *displayOrder = new Characteristic::DisplayOrder(); // <-- This is the new TLV8 Characteristic. Note the constructor has no argument SpanCharacteristic *displayOrder = new Characteristic::DisplayOrder(); // <-- This is the new TLV8 Characteristic. Note the constructor has no argument
HomeSpanTV() : Service::Television() { HomeSpanTV() : Service::Television() {
// Unlike the constructors for numerical and string-based Characteristics (such as ActiveIdentifier and ConfiguredName), // Unlike the constructors for numerical and string-based Characteristics (such as ActiveIdentifier and ConfiguredName),
// we cannot set the initial value of TLV8 Characteristics during construction, but must instead first instantiate the // we cannot set the initial value of TLV8 Characteristics during construction, but must instead first instantiate the
// Characteristic (as we did above), then build a TLV8 object with the information required by the TLV8 Characteristic, and // Characteristic (as we did above), then build a TLV8 object with the information required by the TLV8 Characteristic, and
// then use setTLV() to load the completed TLV8 object into the Characteristic's value. // then use setTLV() to load the completed TLV8 object into the Characteristic's value.
// The (undocumented by Apple!) TLV8 specifications for the DisplayOrder Characteristic are as follows: // The (undocumented by Apple!) TLV8 specifications for the DisplayOrder Characteristic are as follows:
// TAG NAME FORMAT DESCRIPTION // TAG NAME FORMAT DESCRIPTION
// ---- ------------- ------ -------------------------------------------- // ---- ------------- ------ --------------------------------------------
// 0x01 inputSourceID uint32 ID of the Input Source to be displayed first // 0x01 inputSourceID uint32 ID of the Input Source to be displayed first
// 0x00 separator none Empty element to separate the inputSourceIDs // 0x00 separator none Empty element to separate the inputSourceIDs
// 0x01 inputSourceID uint32 ID of the Input Source to be displayed second // 0x01 inputSourceID uint32 ID of the Input Source to be displayed second
// 0x00 separator none Empty element to separate the inputSourceIDs // 0x00 separator none Empty element to separate the inputSourceIDs
// 0x01 inputSourceID uint32 ID of the Input Source to be displayed third // 0x01 inputSourceID uint32 ID of the Input Source to be displayed third
// 0x00 separator none Empty element to separate the inputSourceIDs // 0x00 separator none Empty element to separate the inputSourceIDs
// etc... // etc...
// To start, instantiate a new TLV8 object // To start, instantiate a new TLV8 object
TLV8 orderTLV; // creates an empty TLV8 object TLV8 orderTLV; // creates an empty TLV8 object
// Next, fill it with TAGS and VALUES based on the above specification. The easiest, // Next, fill it with TAGS and VALUES based on the above specification. The easiest, though
// though not necessarily most elegant, way to do this is as follows: // not necessarily most elegant, way to do this is by simply adding each TAG/VALUE as follows:
orderTLV.add(1,10); // TAG=1, VALUE=ID of first Input Source to be displayed orderTLV.add(1,10); // TAG=1, VALUE=ID of first Input Source to be displayed
orderTLV.add(0); // TAG=0 (no value) orderTLV.add(0); // TAG=0 (no value)
orderTLV.add(1,20); // TAG=1, VALUE=ID of the second Input Source to be displayed orderTLV.add(1,20); // TAG=1, VALUE=ID of the second Input Source to be displayed
orderTLV.add(0); // TAG=0 (no value) orderTLV.add(0); // TAG=0 (no value)
orderTLV.add(1,50); // TAG=1, VALUE=ID of the third Input Source to be displayed orderTLV.add(1,50); // TAG=1, VALUE=ID of the third Input Source to be displayed
orderTLV.add(0); // TAG=0 (no value) orderTLV.add(0); // TAG=0 (no value)
orderTLV.add(1,30); // TAG=1, VALUE=ID of the fourth Input Source to be displayed orderTLV.add(1,30); // TAG=1, VALUE=ID of the fourth Input Source to be displayed
orderTLV.add(0); // TAG=0 (no value) orderTLV.add(0); // TAG=0 (no value)
orderTLV.add(1,40); // TAG=1, VALUE=ID of the fifth Input Source to be displayed orderTLV.add(1,40); // TAG=1, VALUE=ID of the fifth Input Source to be displayed
// Based on the above structure, we expect the Home App to display our input sources based on their IDs // Based on the above structure, we expect the Home App to display our input sources based on their IDs
// in the following order: 100, 200, 500, 300, 400. These IDs must of course match the IDs you choose // in the following order: 10, 20, 50, 30, 40. These IDs must of course match the IDs you choose
// for your input sources when you create them at the end of this sketch in setup() // for your input sources when you create them at the end of this sketch in setup()
// The final step is to load this TLV8 object into the DisplayOrder Characteristic // The final step is to load this TLV8 object into the DisplayOrder Characteristic
// displayOrder->setTLV(orderTLV); // set the "value" of DisplayOrder to be the orderTLV object we just created displayOrder->setTLV(orderTLV); // set the "value" of DisplayOrder to be the orderTLV object we just created
// That's it - you've created your first TLV8 Characteristic! // That's it - you've created your first TLV8 Characteristic!
}
// Below we define the usual update() loop. There is nothing "TLV-specific" about this part of the code
boolean update() override {
if(active->updated()){
LOG0("Set TV Power to: %s\n",active->getNewVal()?"ON":"OFF");
} }
// Below we define the usual update() loop. There is nothing "TLV-specific" about this part of the code if(activeID->updated()){
LOG0("Set Input Source to ID=%d\n",activeID->getNewVal());
boolean update() override { }
if(active->updated()){ return(true);
Serial.printf("Set TV Power to: %s\n",active->getNewVal()?"ON":"OFF"); }
}
if(activeID->updated()){
Serial.printf("Set Input Source to ID=%d\n",activeID->getNewVal());
}
return(true);
}
}; };
/////////////////////////////// ///////////////////////////////