diff --git a/src/HomeSpan.cpp b/src/HomeSpan.cpp index 1d0aba7..c6faa3c 100644 --- a/src/HomeSpan.cpp +++ b/src/HomeSpan.cpp @@ -121,6 +121,10 @@ void Span::poll() { homeSpan.Accessories.back()->validate(); } + if(nWarnings>0){ + configLog+="\n*** CAUTION: There " + String((nWarnings>1?"are ":"is ")) + String(nWarnings) + " WARNING" + (nWarnings>1?"S":"") + " associated with this configuration that may lead to the device becoming non-responsive, or operating in an unexpected manner. ***\n"; + } + processSerialCommand("i"); // print homeSpan configuration info if(nFatalErrors>0){ @@ -842,7 +846,7 @@ void Span::processSerialCommand(const char *c){ Serial.print("\n\n"); char d[]="------------------------------"; - Serial.printf("%-30s %s %10s %s %s %s %s %s\n","Service","Type","AID","IID","Update","Loop","Button","Linked Services"); + Serial.printf("%-30s %s %10s %s %s %s %s %s\n","Service","UUID","AID","IID","Update","Loop","Button","Linked Services"); Serial.printf("%.30s %.4s %.10s %.3s %.6s %.4s %.6s %.15s\n",d,d,d,d,d,d,d,d); for(int i=0;iServices.size();j++){ @@ -1277,7 +1281,7 @@ SpanAccessory::SpanAccessory(uint32_t aid){ this->aid=aid; } - homeSpan.configLog+="+Accessory-" + String(this->aid); + homeSpan.configLog+="\u27a4 Accessory: AID=" + String(this->aid); for(int i=0;iaid==homeSpan.Accessories[i]->aid){ @@ -1316,21 +1320,22 @@ void SpanAccessory::validate(){ if(chr->format!=STRING && (chr->uvGet(chr->value) < chr->uvGet(chr->minValue) || chr->uvGet(chr->value) > chr->uvGet(chr->maxValue))){ char c[256]; - sprintf(c," !WARNING: Initial value of %lg for %s-%d is out of range [%llg,%llg]. This may cause device to be non-reponsive!\n", - chr->uvGet(chr->value),chr->hapName,chr->iid,chr->uvGet(chr->minValue),chr->uvGet(chr->maxValue)); + sprintf(c," \u2718 Characteristic %s with IID=%d *** WARNING: Initial value of %lg is out of range [%llg,%llg]. ***\n", + chr->hapName,chr->iid,chr->uvGet(chr->value),chr->uvGet(chr->minValue),chr->uvGet(chr->maxValue)); homeSpan.configLog+=c; + homeSpan.nWarnings++; } } } if(!foundInfo){ - homeSpan.configLog+=" !Service AccessoryInformation"; + homeSpan.configLog+=" \u2718 Service AccessoryInformation"; homeSpan.configLog+=" *** ERROR! Required Service for this Accessory not found. ***\n"; homeSpan.nFatalErrors++; } if(!foundProtocol && (aid==1 || !homeSpan.isBridge)){ // HAPProtocolInformation must always be present in Accessory if aid=1, and any other Accessory if the device is not a bridge) - homeSpan.configLog+=" !Service HAPProtocolInformation"; + homeSpan.configLog+=" \u2718 Service HAPProtocolInformation"; homeSpan.configLog+=" *** ERROR! Required Service for this Accessory not found. ***\n"; homeSpan.nFatalErrors++; } @@ -1366,7 +1371,7 @@ SpanService::SpanService(const char *type, const char *hapName){ this->type=type; this->hapName=hapName; - homeSpan.configLog+="-->Service " + String(hapName); + homeSpan.configLog+=" \u279f Service " + String(hapName); if(homeSpan.Accessories.empty()){ homeSpan.configLog+=" *** ERROR! Can't create new Service without a defined Accessory! ***\n"; @@ -1377,7 +1382,7 @@ SpanService::SpanService(const char *type, const char *hapName){ homeSpan.Accessories.back()->Services.push_back(this); iid=++(homeSpan.Accessories.back()->iidCount); - homeSpan.configLog+="-" + String(iid) + String(" (") + String(type) + String(") "); + homeSpan.configLog+=": IID=" + String(iid) + ", UUID=0x" + String(type); if(!strcmp(this->type,"3E") && iid!=1){ homeSpan.configLog+=" *** ERROR! The AccessoryInformation Service must be defined before any other Services in an Accessory. ***"; @@ -1455,8 +1460,9 @@ void SpanService::validate(){ valid=!strcmp(req[i]->type,Characteristics[j]->type); if(!valid){ - homeSpan.configLog+=" !Characteristic " + String(req[i]->hapName); + homeSpan.configLog+=" \u2718 Characteristic " + String(req[i]->hapName); homeSpan.configLog+=" *** WARNING! Required Characteristic for this Service not found. ***\n"; + homeSpan.nWarnings++; } } @@ -1475,7 +1481,7 @@ SpanCharacteristic::SpanCharacteristic(HapChar *hapChar){ format=hapChar->format; staticRange=hapChar->staticRange; - homeSpan.configLog+="---->Characteristic " + String(hapName); + homeSpan.configLog+=" \u21e8 Characteristic " + String(hapName); if(homeSpan.Accessories.empty() || homeSpan.Accessories.back()->Services.empty()){ homeSpan.configLog+=" *** ERROR! Can't create new Characteristic without a defined Service! ***\n"; @@ -1488,35 +1494,6 @@ SpanCharacteristic::SpanCharacteristic(HapChar *hapChar){ aid=homeSpan.Accessories.back()->aid; ev=(boolean *)calloc(homeSpan.maxConnections,sizeof(boolean)); - - homeSpan.configLog+="-" + String(iid) + String(" (") + String(type) + String(") "); - - boolean valid=false; - - for(int i=0; !valid && iServices.back()->req.size(); i++) - valid=!strcmp(type,homeSpan.Accessories.back()->Services.back()->req[i]->type); - - for(int i=0; !valid && iServices.back()->opt.size(); i++) - valid=!strcmp(type,homeSpan.Accessories.back()->Services.back()->opt[i]->type); - - if(!valid){ - homeSpan.configLog+=" *** ERROR! Service does not support this Characteristic. ***"; - homeSpan.nFatalErrors++; - } - - boolean repeated=false; - - for(int i=0; !repeated && iServices.back()->Characteristics.size(); i++) - repeated=!strcmp(type,homeSpan.Accessories.back()->Services.back()->Characteristics[i]->type); - - if(valid && repeated){ - homeSpan.configLog+=" *** ERROR! Characteristic already defined for this Service. ***"; - homeSpan.nFatalErrors++; - } - - homeSpan.Accessories.back()->Services.back()->Characteristics.push_back(this); - - homeSpan.configLog+="\n"; } /////////////////////////////// @@ -1676,7 +1653,7 @@ unsigned long SpanCharacteristic::timeVal(){ SpanRange::SpanRange(int min, int max, int step){ if(homeSpan.Accessories.empty() || homeSpan.Accessories.back()->Services.empty() || homeSpan.Accessories.back()->Services.back()->Characteristics.empty() ){ - homeSpan.configLog+="------>SpanRange: *** ERROR! Can't create new Range without a defined Characteristic! ***\n"; + homeSpan.configLog+=" \u2718 SpanRange: *** ERROR! Can't create new Range without a defined Characteristic! ***\n"; homeSpan.nFatalErrors++; } else { homeSpan.Accessories.back()->Services.back()->Characteristics.back()->setRange(min,max,step); @@ -1689,7 +1666,7 @@ SpanRange::SpanRange(int min, int max, int step){ SpanButton::SpanButton(int pin, uint16_t longTime, uint16_t singleTime, uint16_t doubleTime){ - homeSpan.configLog+="---->SpanButton: Pin=" + String(pin) + " Long/Single/Double=" + String(longTime) + "/" + String(singleTime) + "/" + String(doubleTime) + " ms"; + homeSpan.configLog+=" \u25bc SpanButton: Pin=" + String(pin) + ", Single=" + String(singleTime) + "ms, Double=" + String(doubleTime) + "ms, Long=" + String(longTime) + "ms"; if(homeSpan.Accessories.empty() || homeSpan.Accessories.back()->Services.empty()){ homeSpan.configLog+=" *** ERROR! Can't create new PushButton without a defined Service! ***\n"; @@ -1707,8 +1684,10 @@ SpanButton::SpanButton(int pin, uint16_t longTime, uint16_t singleTime, uint16_t this->doubleTime=doubleTime; service=homeSpan.Accessories.back()->Services.back(); - if((void(*)(int,int))(service->*(&SpanService::button))==(void(*)(int,int))(&SpanService::button)) + if((void(*)(int,int))(service->*(&SpanService::button))==(void(*)(int,int))(&SpanService::button)){ homeSpan.configLog+=" *** WARNING: No button() method defined for this PushButton! ***"; + homeSpan.nWarnings++; + } pushButton=new PushButton(pin); // create underlying PushButton diff --git a/src/HomeSpan.h b/src/HomeSpan.h index 6744bd7..fbf2cde 100644 --- a/src/HomeSpan.h +++ b/src/HomeSpan.h @@ -100,6 +100,7 @@ struct Span{ unsigned long snapTime; // current time (in millis) snapped before entering Service loops() or updates() boolean isInitialized=false; // flag indicating HomeSpan has been initialized int nFatalErrors=0; // number of fatal errors in user-defined configuration + int nWarnings=0; // number of warnings errors in user-defined configuration String configLog; // log of configuration process, including any errors boolean isBridge=true; // flag indicating whether device is configured as a bridge (i.e. first Accessory contains nothing but AccessoryInformation and HAPProtocolInformation) HapQR qrCode; // optional QR Code to use for pairing @@ -342,7 +343,7 @@ struct SpanCharacteristic{ template SpanCharacteristic *setRange(A min, B max, S step=0){ char c[256]; - homeSpan.configLog+=String("------>Set Range for ") + String(hapName) + "-" + String(iid); + homeSpan.configLog+=String(" \u2b0c Set Range for ") + String(hapName) + " with IID=" + String(iid); if(customRange){ sprintf(c," *** ERROR! Range already set for this Characteristic! ***\n"); @@ -360,9 +361,9 @@ struct SpanCharacteristic{ customRange=true; if(uvGet(stepValue)>0) - sprintf(c,": %s/%s/%s\n",uvPrint(minValue),uvPrint(maxValue),uvPrint(stepValue)); + sprintf(c,": Min=%s, Max=%s, Step=%s\n",uvPrint(minValue),uvPrint(maxValue),uvPrint(stepValue)); else - sprintf(c,": %s/%s\n",uvPrint(minValue),uvPrint(maxValue)); + sprintf(c,": Min=%s, Max=%s\n",uvPrint(minValue),uvPrint(maxValue)); } homeSpan.configLog+=c; return(this); @@ -376,7 +377,38 @@ struct SpanCharacteristic{ uvSet(minValue,min); uvSet(maxValue,max); uvSet(stepValue,0); - + + homeSpan.configLog+="(" + uvPrint(value) + ")" + ": IID=" + String(iid) + ", UUID=0x" + String(type); + if(format!=STRING && format!=BOOL) + homeSpan.configLog+= " Range=[" + String(uvPrint(minValue)) + "," + String(uvPrint(maxValue)) + "]"; + + boolean valid=false; + + for(int i=0; !valid && iServices.back()->req.size(); i++) + valid=!strcmp(type,homeSpan.Accessories.back()->Services.back()->req[i]->type); + + for(int i=0; !valid && iServices.back()->opt.size(); i++) + valid=!strcmp(type,homeSpan.Accessories.back()->Services.back()->opt[i]->type); + + if(!valid){ + homeSpan.configLog+=" *** ERROR! Service does not support this Characteristic. ***"; + homeSpan.nFatalErrors++; + } + + boolean repeated=false; + + for(int i=0; !repeated && iServices.back()->Characteristics.size(); i++) + repeated=!strcmp(type,homeSpan.Accessories.back()->Services.back()->Characteristics[i]->type); + + if(valid && repeated){ + homeSpan.configLog+=" *** ERROR! Characteristic already defined for this Service. ***"; + homeSpan.nFatalErrors++; + } + + homeSpan.Accessories.back()->Services.back()->Characteristics.push_back(this); + + homeSpan.configLog+="\n"; + } // init() template T getVal(){ diff --git a/src/src.ino b/src/src.ino index eff4b47..3becb91 100644 --- a/src/src.ino +++ b/src/src.ino @@ -14,7 +14,7 @@ void setup() { homeSpan.setPortNum(1201); // homeSpan.setMaxConnections(6); // homeSpan.setQRID("One1"); - homeSpan.enableOTA(); +// homeSpan.enableOTA(); homeSpan.setSketchVersion("Test 1.3.1"); homeSpan.setWifiCallback(wifiEstablished); @@ -30,20 +30,21 @@ void setup() { new Characteristic::FirmwareRevision(HOMESPAN_VERSION); // Firmware of the Accessory (arbitrary text string, and can be the same for every Accessory) new Characteristic::Identify(); // Create the required Identify - new Service::HAPProtocolInformation(); // Create the HAP Protcol Information Service +// new Service::HAPProtocolInformation(); // Create the HAP Protcol Information Service new Characteristic::Version("1.1.0"); // Set the Version Characteristic to "1.1.0" as required by HAP new Service::LightBulb(); - new Characteristic::On(); +// new Characteristic::On(); new Characteristic::Brightness(); new Characteristic::Name("Light 1"); new Service::LightBulb(); - new Characteristic::On(); - new Characteristic::Brightness(); + new Characteristic::On(2); + (new Characteristic::Brightness(150))->setRange(0,140,5); new Characteristic::Name("Light 2"); (new Service::Switch())->setPrimary(); new Characteristic::On(); new Characteristic::Name("Switch 3"); + new SpanButton(17); } // end of setup()