diff --git a/src/HomeSpan.h b/src/HomeSpan.h index e10c32a..2938f4a 100644 --- a/src/HomeSpan.h +++ b/src/HomeSpan.h @@ -509,7 +509,7 @@ class SpanCharacteristic{ StatusCode loadUpdate(char *val, char *ev, boolean wr); // load updated val/ev from PUT /characteristic JSON request. Return intitial HAP status code (checks to see if characteristic is found, is writable, etc.) String uvPrint(UVal &u){ - char c[67]; // space for 64 characters + surrounding quotes + terminating null + char c[64]; switch(format){ case FORMAT::BOOL: return(String(u.BOOL)); @@ -530,8 +530,7 @@ class SpanCharacteristic{ case FORMAT::STRING: case FORMAT::DATA: case FORMAT::TLV_ENC: - sprintf(c,"\"%.64s\"",u.STRING); // Truncating string to 64 chars - return(String(c)); + return(String("\"") + String(u.STRING) + String("\"")); } // switch return(String()); // included to prevent compiler warnings } diff --git a/src/Span.h b/src/Span.h index 1dc1395..23bba59 100644 --- a/src/Span.h +++ b/src/Span.h @@ -616,6 +616,10 @@ namespace Characteristic { HapChar _CUSTOM_##NAME {#UUID,#NAME,(PERMS)(PERMISISONS),DATA,true}; \ namespace Characteristic { struct NAME : SpanCharacteristic { NAME(const char * val="AA==", boolean nvsStore=false) : SpanCharacteristic {&_CUSTOM_##NAME,true} { init(val,nvsStore); } }; } +#define CUSTOM_CHAR_TLV(NAME,UUID,PERMISISONS) \ + HapChar _CUSTOM_##NAME {#UUID,#NAME,(PERMS)(PERMISISONS),TLV_ENC,true}; \ + namespace Characteristic { struct NAME : SpanCharacteristic { NAME(const char * val="", boolean nvsStore=false) : SpanCharacteristic {&_CUSTOM_##NAME,true} { init(val,nvsStore); } }; } + #else #define CUSTOM_CHAR(NAME,UUID,PERMISISONS,FORMAT,DEFVAL,MINVAL,MAXVAL,STATIC_RANGE) \ diff --git a/src/src.ino b/src/src.ino index 19677e5..01f20f2 100644 --- a/src/src.ino +++ b/src/src.ino @@ -28,45 +28,218 @@ #include "HomeSpan.h" #include "TLV8.h" -#define MAX_LIGHTS 1 +CUSTOM_CHAR_TLV(DisplayOrder,136,PR+EV); -CUSTOM_CHAR_DATA(UserData, AAAAAAAA-BBBB-AAAA-AAAA-AAAAAAAAAAAA, PR+PW+EV); +struct HomeSpanTV : Service::Television { + + SpanCharacteristic *active = new Characteristic::Active(0); // TV On/Off (set to Off at start-up) + SpanCharacteristic *activeID = new Characteristic::ActiveIdentifier(3); // Sets HDMI 3 on start-up + SpanCharacteristic *remoteKey = new Characteristic::RemoteKey(); // Used to receive button presses from the Remote Control widget + SpanCharacteristic *settingsKey = new Characteristic::PowerModeSelection(); // Adds "View TV Setting" option to Selection Screen + SpanCharacteristic *displayOrder = new Characteristic::DisplayOrder(); + + HomeSpanTV(const char *name) : Service::Television() { + new Characteristic::ConfiguredName(name); // Name of TV + Serial.printf("Configured TV: %s\n",name); + + TLV8 orderTLV; + uint32_t order[]={5,10,6,2,1,9,11,3,18,12}; + + for(int i=0;i0) + orderTLV.add(0); + orderTLV.add(1,sizeof(uint32_t),(uint8_t*)(order+i)); + } + + orderTLV.print(); + size_t n=orderTLV.pack_size(); + Serial.printf("Size=%d\n",n); + uint8_t c[n]; + orderTLV.pack(c); + displayOrder->setData(c,n); + + new SpanUserCommand('P', "- change order of inputs", changeOrder, this); + } + + boolean update() override { + + if(active->updated()){ + Serial.printf("Set TV Power to: %s\n",active->getNewVal()?"ON":"OFF"); + } + + if(activeID->updated()){ + Serial.printf("Set Input Source to HDMI-%d\n",activeID->getNewVal()); + } + + if(settingsKey->updated()){ + Serial.printf("Received request to \"View TV Settings\"\n"); + } + + if(remoteKey->updated()){ + Serial.printf("Remote Control key pressed: "); + switch(remoteKey->getNewVal()){ + case 4: + Serial.printf("UP ARROW\n"); + break; + case 5: + Serial.printf("DOWN ARROW\n"); + break; + case 6: + Serial.printf("LEFT ARROW\n"); + break; + case 7: + Serial.printf("RIGHT ARROW\n"); + break; + case 8: + Serial.printf("SELECT\n"); + break; + case 9: + Serial.printf("BACK\n"); + break; + case 11: + Serial.printf("PLAY/PAUSE\n"); + break; + case 15: + Serial.printf("INFO\n"); + break; + default: + Serial.print("UNKNOWN KEY\n"); + } + } + + return(true); + } + + static void changeOrder(const char *buf, void *arg){ + HomeSpanTV *hsTV=(HomeSpanTV *)arg; + + TLV8 orderTLV; + uint32_t order[]={12,10,6,2,1,9,11,3,18,5}; + + for(int i=0;i0) + orderTLV.add(0); + orderTLV.add(1,sizeof(uint32_t),(uint8_t*)(order+i)); + } + + orderTLV.print(); + size_t n=orderTLV.pack_size(); + Serial.printf("Size=%d\n",n); + uint8_t c[n]; + orderTLV.pack(c); + hsTV->displayOrder->setData(c,n); + } + +}; + +/////////////////////////////// void setup() { - + Serial.begin(115200); homeSpan.setLogLevel(2); + + homeSpan.begin(Category::Television,"HomeSpan Television"); - homeSpan.begin(Category::Lighting,"HomeSpan Max"); + SPAN_ACCESSORY(); + + SpanService *hdmi1 = new Service::InputSource(); // Source included in Selection List, but excluded from Settings Screen + new Characteristic::ConfiguredName("Alpha"); + new Characteristic::Identifier(5); + new Characteristic::IsConfigured(1); + new Characteristic::CurrentVisibilityState(0); + new Characteristic::TargetVisibilityState(0); - new SpanAccessory(); - new Service::AccessoryInformation(); - new Characteristic::Identify(); + SpanService *hdmi2 = new Service::InputSource(); + new Characteristic::ConfiguredName("Gamma"); + new Characteristic::Identifier(10); + new Characteristic::IsConfigured(1); + new Characteristic::CurrentVisibilityState(0); + new Characteristic::TargetVisibilityState(0); - for(int i=0;isetDescription("Custom Data")->setData(x,5); - char c[30]; - sprintf(c,"Light-%d",i); - new Characteristic::Name(c); - new Service::LightBulb(); - new Characteristic::On(0,false); - WEBLOG("Configuring %s",c); - } + SpanService *hdmi3 = new Service::InputSource(); + new Characteristic::ConfiguredName("Beta"); + new Characteristic::Identifier(6); + new Characteristic::IsConfigured(1); + new Characteristic::CurrentVisibilityState(0); + new Characteristic::TargetVisibilityState(0); + SpanService *hdmi4 = new Service::InputSource(); + new Characteristic::ConfiguredName("Zebra"); + new Characteristic::Identifier(2); + new Characteristic::IsConfigured(1); + new Characteristic::CurrentVisibilityState(0); + new Characteristic::TargetVisibilityState(0); + + SpanService *hdmi5 = new Service::InputSource(); + new Characteristic::ConfiguredName("Delta"); + new Characteristic::Identifier(1); + new Characteristic::IsConfigured(1); + new Characteristic::CurrentVisibilityState(0); + new Characteristic::TargetVisibilityState(0); + + SpanService *hdmi6 = new Service::InputSource(); + new Characteristic::ConfiguredName("Trident"); + new Characteristic::Identifier(9); + new Characteristic::IsConfigured(1); + new Characteristic::CurrentVisibilityState(0); + new Characteristic::TargetVisibilityState(0); + + SpanService *hdmi7 = new Service::InputSource(); + new Characteristic::ConfiguredName("Netflix"); + new Characteristic::Identifier(11); + new Characteristic::IsConfigured(1); + new Characteristic::CurrentVisibilityState(0); + new Characteristic::TargetVisibilityState(0); + + SpanService *hdmi8 = new Service::InputSource(); + new Characteristic::ConfiguredName("Alpha2"); + new Characteristic::Identifier(3); + new Characteristic::IsConfigured(1); + new Characteristic::CurrentVisibilityState(0); + new Characteristic::TargetVisibilityState(0); + + SpanService *hdmi9 = new Service::InputSource(); + new Characteristic::ConfiguredName("Moon"); + new Characteristic::Identifier(18); + new Characteristic::IsConfigured(1); + new Characteristic::CurrentVisibilityState(0); + new Characteristic::TargetVisibilityState(0); + + SpanService *hdmi10 = new Service::InputSource(); + new Characteristic::ConfiguredName("Gamba"); + new Characteristic::Identifier(12); + new Characteristic::IsConfigured(1); + new Characteristic::CurrentVisibilityState(0); + new Characteristic::TargetVisibilityState(0); + + SpanService *speaker = new Service::TelevisionSpeaker(); + new Characteristic::VolumeSelector(); + new Characteristic::VolumeControlType(3); + + (new HomeSpanTV("Test TV")) // Define a Television Service. Must link in InputSources! + ->addLink(hdmi1) + ->addLink(hdmi2) + ->addLink(hdmi3) + ->addLink(hdmi4) + ->addLink(hdmi5) + ->addLink(hdmi6) + ->addLink(hdmi7) + ->addLink(hdmi8) + ->addLink(hdmi9) + ->addLink(hdmi10) + ->addLink(speaker) + ; + } + ////////////////////////////////////// void loop(){ - homeSpan.poll(); - delay(100000); - + homeSpan.poll(); } //////////////////////////////////////