diff --git a/Other Examples/Television/Television.ino b/Other Examples/Television/Television.ino index 9306dbc..4079c11 100644 --- a/Other Examples/Television/Television.ino +++ b/Other Examples/Television/Television.ino @@ -87,20 +87,31 @@ struct HKTV : Service::Television { struct TV_Source : Service::InputSource{ - SpanCharacteristic *currentState = new Characteristic::CurrentVisibilityState(0); - SpanCharacteristic *targetState = new Characteristic::TargetVisibilityState(0); + SpanCharacteristic *currentState = new Characteristic::CurrentVisibilityState(0,true); + SpanCharacteristic *targetState = new Characteristic::TargetVisibilityState(0,true); + SpanCharacteristic *configName = new Characteristic::ConfiguredName("HDMI 12",true); TV_Source() : Service::InputSource(){ - new Characteristic::ConfiguredName("HDMI 12"); +// new Characteristic::ConfiguredName("HDMI 12"); new Characteristic::Identifier(12); new Characteristic::IsConfigured(1); } boolean update() override{ + char c[50]; + sprintf(c,"HERE I AM "); + if(targetState->updated()){ - Serial.printf("New Target State = %d\n",targetState->getNewVal()); + Serial.printf("Old Target State = %d New Target State = %d\n",targetState->getVal(),targetState->getNewVal()); currentState->setVal(targetState->getNewVal()); + Serial.printf("Name: %s\n",configName->getString()); + configName->setString(c); + Serial.printf("Name: %s\n",configName->getString()); + } + + if(configName->updated()){ + Serial.printf("CURRENT NAME: %s NEW NAME: %s\n",configName->getString(),configName->getNewString()); } return(true); diff --git a/src/HomeSpan.cpp b/src/HomeSpan.cpp index dd7ab1b..b6a77dc 100644 --- a/src/HomeSpan.cpp +++ b/src/HomeSpan.cpp @@ -1206,14 +1206,17 @@ int Span::updateCharacteristics(char *buf, SpanBuf *pObj){ LOG1(" iid="); LOG1(pObj[j].characteristic->iid); if(status==StatusCode::OK){ // if status is okay - pObj[j].characteristic->value=pObj[j].characteristic->newValue; // update characteristic value with new value + pObj[j].characteristic->uvSet(pObj[j].characteristic->value,pObj[j].characteristic->newValue); // update characteristic value with new value if(pObj[j].characteristic->nvsKey){ // if storage key found - nvs_set_blob(charNVS,pObj[j].characteristic->nvsKey,&(pObj[j].characteristic->value),sizeof(pObj[j].characteristic->value)); // store data + if(pObj[j].characteristic->format != FORMAT::STRING) + nvs_set_blob(charNVS,pObj[j].characteristic->nvsKey,&(pObj[j].characteristic->value),sizeof(pObj[j].characteristic->value)); // store data + else + nvs_set_str(charNVS,pObj[j].characteristic->nvsKey,pObj[j].characteristic->value.STRING); // store data nvs_commit(charNVS); } LOG1(" (okay)\n"); } else { // if status not okay - pObj[j].characteristic->newValue=pObj[j].characteristic->value; // replace characteristic new value with original value + pObj[j].characteristic->uvSet(pObj[j].characteristic->newValue,pObj[j].characteristic->value); // replace characteristic new value with original value LOG1(" (failed)\n"); } pObj[j].characteristic->isUpdated=false; // reset isUpdated flag for characteristic @@ -1728,8 +1731,7 @@ StatusCode SpanCharacteristic::loadUpdate(char *val, char *ev){ break; case STRING: - newValue.STRING = (char *)realloc(newValue.STRING, strlen(val) + 1); - strcpy(newValue.STRING, val); + uvSet(newValue,(const char *)val); break; default: diff --git a/src/HomeSpan.h b/src/HomeSpan.h index cde9021..61af4ac 100644 --- a/src/HomeSpan.h +++ b/src/HomeSpan.h @@ -307,25 +307,20 @@ struct SpanCharacteristic{ return(String()); // included to prevent compiler warnings } + void uvSet(UVal &dest, UVal &src){ + if(format==FORMAT::STRING) + uvSet(dest,(const char *)src.STRING); + else + dest=src; + } + void uvSet(UVal &u, const char *val){ + Serial.printf("ADDRESS %d ",u.UINT32); u.STRING = (char *)realloc(u.STRING, strlen(val) + 1); + Serial.printf("-> %d \n",u.UINT32); strcpy(u.STRING, val); } - char *getString(){ - if(format == FORMAT::STRING) - return value.STRING; - - return NULL; - } - - char *getNewString(){ - if(format == FORMAT::STRING) - return newValue.STRING; - - return NULL; - } - template void uvSet(UVal &u, T val){ switch(format){ case FORMAT::BOOL: @@ -369,9 +364,6 @@ struct SpanCharacteristic{ return((T) u.UINT64); case FORMAT::FLOAT: return((T) u.FLOAT); - case FORMAT::STRING: - Serial.print("\n*** WARNING: Can't use getVal() or getNewVal() with string Characteristics.\n\n"); - return(0); } return(0); // included to prevent compiler warnings } @@ -409,9 +401,41 @@ struct SpanCharacteristic{ template void init(T val, boolean nvsStore, A min=0, B max=1){ int nvsFlag=0; - uvSet(value,val); - uvSet(newValue,val); + + if(nvsStore){ + nvsKey=(char *)malloc(16); + uint16_t t; + sscanf(type,"%x",&t); + sprintf(nvsKey,"%04X%08X%03X",t,aid,iid&0xFFF); + size_t len; + + if(format != FORMAT::STRING){ + if(!nvs_get_blob(homeSpan.charNVS,nvsKey,NULL,&len)){ + nvs_get_blob(homeSpan.charNVS,nvsKey,&value,&len); + nvsFlag=2; + } + else { + nvs_set_blob(homeSpan.charNVS,nvsKey,&value,sizeof(UVal)); // store data + nvs_commit(homeSpan.charNVS); // commit to NVS + nvsFlag=1; + } + } else { + if(!nvs_get_str(homeSpan.charNVS,nvsKey,NULL,&len)){ + char c[len]; + nvs_get_str(homeSpan.charNVS,nvsKey,c,&len); + uvSet(value,(const char *)c); + nvsFlag=2; + } + else { + nvs_set_str(homeSpan.charNVS,nvsKey,value.STRING); // store string data + nvs_commit(homeSpan.charNVS); // commit to NVS + nvsFlag=1; + } + } + } + + uvSet(newValue,value); if(format != FORMAT::STRING) { uvSet(minValue,min); @@ -419,25 +443,6 @@ struct SpanCharacteristic{ uvSet(stepValue,0); } - if(nvsStore){ - nvsKey=(char *)malloc(16); - uint16_t t; - sscanf(type,"%x",&t); - sprintf(nvsKey,"%04X%08X%03X",t,aid,iid&0xFFF); - size_t len; - - if(!nvs_get_blob(homeSpan.charNVS,nvsKey,NULL,&len)){ - nvs_get_blob(homeSpan.charNVS,nvsKey,&value,&len); - newValue=value; - nvsFlag=2; - } - else { - nvs_set_blob(homeSpan.charNVS,nvsKey,&value,sizeof(UVal)); // store data - nvs_commit(homeSpan.charNVS); // commit to NVS - nvsFlag=1; - } - } - homeSpan.configLog+="(" + uvPrint(value) + ")" + ": IID=" + String(iid) + ", UUID=0x" + String(type); if(format!=FORMAT::STRING && format!=FORMAT::BOOL) homeSpan.configLog+= " Range=[" + String(uvPrint(minValue)) + "," + String(uvPrint(maxValue)) + "]"; @@ -476,6 +481,7 @@ struct SpanCharacteristic{ } // init() + template T getVal(){ return(uvGet(value)); } @@ -484,6 +490,46 @@ struct SpanCharacteristic{ return(uvGet(newValue)); } + char *getString(){ + if(format == FORMAT::STRING) + return value.STRING; + + return NULL; + } + + char *getNewString(){ + if(format == FORMAT::STRING) + return newValue.STRING; + + return NULL; + } + + void setString(const char *val){ + + if((perms & EV) == 0){ + Serial.printf("\n*** WARNING: Attempt to update Characteristic::%s with setVal() ignored. No NOTIFICATION permission on this characteristic\n\n",hapName); + return; + } + + uvSet(value,val); + uvSet(newValue,value); + + updateTime=homeSpan.snapTime; + + SpanBuf sb; // create SpanBuf object + sb.characteristic=this; // set characteristic + sb.status=StatusCode::OK; // set status + char dummy[]=""; + sb.val=dummy; // set dummy "val" so that sprintfNotify knows to consider this "update" + homeSpan.Notifications.push_back(sb); // store SpanBuf in Notifications vector + + if(nvsKey){ + nvs_set_str(homeSpan.charNVS,nvsKey,value.STRING); // store data + nvs_commit(homeSpan.charNVS); + } + + } // setString() + template void setVal(T val){ if((perms & EV) == 0){ @@ -491,13 +537,13 @@ struct SpanCharacteristic{ return; } - if(format!=FORMAT::STRING && ( val < uvGet(minValue) || val > uvGet(maxValue))){ + if(val < uvGet(minValue) || val > uvGet(maxValue)){ Serial.printf("\n*** WARNING: Attempt to update Characteristic::%s with setVal(%llg) is out of range [%llg,%llg]. This may cause device to become non-reponsive!\n\n", hapName,(double)val,uvGet(minValue),uvGet(maxValue)); } uvSet(value,val); - uvSet(newValue,val); + uvSet(newValue,value); updateTime=homeSpan.snapTime;