Updated logic re STRING Characteristics

Added setString() as analog to setVal().  This complements getString and getNewString() which are analogs to getVal() and getNewVal().
This commit is contained in:
Gregg 2021-10-23 13:16:49 -05:00
parent dcbfbc3e15
commit b90fc5aad5
3 changed files with 108 additions and 49 deletions

View File

@ -87,20 +87,31 @@ struct HKTV : Service::Television {
struct TV_Source : Service::InputSource{ struct TV_Source : Service::InputSource{
SpanCharacteristic *currentState = new Characteristic::CurrentVisibilityState(0); SpanCharacteristic *currentState = new Characteristic::CurrentVisibilityState(0,true);
SpanCharacteristic *targetState = new Characteristic::TargetVisibilityState(0); SpanCharacteristic *targetState = new Characteristic::TargetVisibilityState(0,true);
SpanCharacteristic *configName = new Characteristic::ConfiguredName("HDMI 12",true);
TV_Source() : Service::InputSource(){ TV_Source() : Service::InputSource(){
new Characteristic::ConfiguredName("HDMI 12"); // new Characteristic::ConfiguredName("HDMI 12");
new Characteristic::Identifier(12); new Characteristic::Identifier(12);
new Characteristic::IsConfigured(1); new Characteristic::IsConfigured(1);
} }
boolean update() override{ boolean update() override{
char c[50];
sprintf(c,"HERE I AM ");
if(targetState->updated()){ 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()); 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); return(true);

View File

@ -1206,14 +1206,17 @@ int Span::updateCharacteristics(char *buf, SpanBuf *pObj){
LOG1(" iid="); LOG1(" iid=");
LOG1(pObj[j].characteristic->iid); LOG1(pObj[j].characteristic->iid);
if(status==StatusCode::OK){ // if status is okay 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 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); nvs_commit(charNVS);
} }
LOG1(" (okay)\n"); LOG1(" (okay)\n");
} else { // if status not okay } 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"); LOG1(" (failed)\n");
} }
pObj[j].characteristic->isUpdated=false; // reset isUpdated flag for characteristic pObj[j].characteristic->isUpdated=false; // reset isUpdated flag for characteristic
@ -1728,8 +1731,7 @@ StatusCode SpanCharacteristic::loadUpdate(char *val, char *ev){
break; break;
case STRING: case STRING:
newValue.STRING = (char *)realloc(newValue.STRING, strlen(val) + 1); uvSet(newValue,(const char *)val);
strcpy(newValue.STRING, val);
break; break;
default: default:

View File

@ -307,25 +307,20 @@ struct SpanCharacteristic{
return(String()); // included to prevent compiler warnings 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){ void uvSet(UVal &u, const char *val){
Serial.printf("ADDRESS %d ",u.UINT32);
u.STRING = (char *)realloc(u.STRING, strlen(val) + 1); u.STRING = (char *)realloc(u.STRING, strlen(val) + 1);
Serial.printf("-> %d \n",u.UINT32);
strcpy(u.STRING, val); 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 <typename T> void uvSet(UVal &u, T val){ template <typename T> void uvSet(UVal &u, T val){
switch(format){ switch(format){
case FORMAT::BOOL: case FORMAT::BOOL:
@ -369,9 +364,6 @@ struct SpanCharacteristic{
return((T) u.UINT64); return((T) u.UINT64);
case FORMAT::FLOAT: case FORMAT::FLOAT:
return((T) u.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 return(0); // included to prevent compiler warnings
} }
@ -409,15 +401,7 @@ struct SpanCharacteristic{
template <typename T, typename A=boolean, typename B=boolean> void init(T val, boolean nvsStore, A min=0, B max=1){ template <typename T, typename A=boolean, typename B=boolean> void init(T val, boolean nvsStore, A min=0, B max=1){
int nvsFlag=0; int nvsFlag=0;
uvSet(value,val); uvSet(value,val);
uvSet(newValue,val);
if(format != FORMAT::STRING) {
uvSet(minValue,min);
uvSet(maxValue,max);
uvSet(stepValue,0);
}
if(nvsStore){ if(nvsStore){
nvsKey=(char *)malloc(16); nvsKey=(char *)malloc(16);
@ -426,18 +410,39 @@ struct SpanCharacteristic{
sprintf(nvsKey,"%04X%08X%03X",t,aid,iid&0xFFF); sprintf(nvsKey,"%04X%08X%03X",t,aid,iid&0xFFF);
size_t len; size_t len;
if(!nvs_get_blob(homeSpan.charNVS,nvsKey,NULL,&len)){ if(format != FORMAT::STRING){
nvs_get_blob(homeSpan.charNVS,nvsKey,&value,&len); if(!nvs_get_blob(homeSpan.charNVS,nvsKey,NULL,&len)){
newValue=value; nvs_get_blob(homeSpan.charNVS,nvsKey,&value,&len);
nvsFlag=2; nvsFlag=2;
} }
else { else {
nvs_set_blob(homeSpan.charNVS,nvsKey,&value,sizeof(UVal)); // store data nvs_set_blob(homeSpan.charNVS,nvsKey,&value,sizeof(UVal)); // store data
nvs_commit(homeSpan.charNVS); // commit to NVS nvs_commit(homeSpan.charNVS); // commit to NVS
nvsFlag=1; 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);
uvSet(maxValue,max);
uvSet(stepValue,0);
}
homeSpan.configLog+="(" + uvPrint(value) + ")" + ": IID=" + String(iid) + ", UUID=0x" + String(type); homeSpan.configLog+="(" + uvPrint(value) + ")" + ": IID=" + String(iid) + ", UUID=0x" + String(type);
if(format!=FORMAT::STRING && format!=FORMAT::BOOL) if(format!=FORMAT::STRING && format!=FORMAT::BOOL)
homeSpan.configLog+= " Range=[" + String(uvPrint(minValue)) + "," + String(uvPrint(maxValue)) + "]"; homeSpan.configLog+= " Range=[" + String(uvPrint(minValue)) + "," + String(uvPrint(maxValue)) + "]";
@ -476,6 +481,7 @@ struct SpanCharacteristic{
} // init() } // init()
template <class T=int> T getVal(){ template <class T=int> T getVal(){
return(uvGet<T>(value)); return(uvGet<T>(value));
} }
@ -484,6 +490,46 @@ struct SpanCharacteristic{
return(uvGet<T>(newValue)); return(uvGet<T>(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 <typename T> void setVal(T val){ template <typename T> void setVal(T val){
if((perms & EV) == 0){ if((perms & EV) == 0){
@ -491,13 +537,13 @@ struct SpanCharacteristic{
return; return;
} }
if(format!=FORMAT::STRING && ( val < uvGet<T>(minValue) || val > uvGet<T>(maxValue))){ if(val < uvGet<T>(minValue) || val > uvGet<T>(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", 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<double>(minValue),uvGet<double>(maxValue)); hapName,(double)val,uvGet<double>(minValue),uvGet<double>(maxValue));
} }
uvSet(value,val); uvSet(value,val);
uvSet(newValue,val); uvSet(newValue,value);
updateTime=homeSpan.snapTime; updateTime=homeSpan.snapTime;