Added ability to specify "aid" for Accessories
If not specified, "aid" defaults to an index number representing the order in which the Accessories were created. Values are stored as uint32_t (which is more limited than HAP requirements of uint64_t, but makes the code easier). TO DO: Must add validation to ensure duplicate aid values are not used.
This commit is contained in:
parent
da489b4d94
commit
1847478252
|
|
@ -649,14 +649,14 @@ void Span::processSerialCommand(char *c){
|
||||||
|
|
||||||
char d[]="------------------------------";
|
char d[]="------------------------------";
|
||||||
char cBuf[256];
|
char cBuf[256];
|
||||||
sprintf(cBuf,"%-30s %s %s %s %s %s %s\n","Service","Type","AID","IID","Update","Loop","Button");
|
sprintf(cBuf,"%-30s %s %10s %s %s %s %s\n","Service","Type","AID","IID","Update","Loop","Button");
|
||||||
Serial.print(cBuf);
|
Serial.print(cBuf);
|
||||||
sprintf(cBuf,"%.30s %.4s %.3s %.3s %.6s %.4s %.6s\n",d,d,d,d,d,d,d);
|
sprintf(cBuf,"%.30s %.4s %.10s %.3s %.6s %.4s %.6s\n",d,d,d,d,d,d,d);
|
||||||
Serial.print(cBuf);
|
Serial.print(cBuf);
|
||||||
for(int i=0;i<Accessories.size();i++){ // identify all services with over-ridden loop() methods
|
for(int i=0;i<Accessories.size();i++){ // identify all services with over-ridden loop() methods
|
||||||
for(int j=0;j<Accessories[i]->Services.size();j++){
|
for(int j=0;j<Accessories[i]->Services.size();j++){
|
||||||
SpanService *s=Accessories[i]->Services[j];
|
SpanService *s=Accessories[i]->Services[j];
|
||||||
sprintf(cBuf,"%-30s %4s %3d %3d %6s %4s %6s\n",s->hapName,s->type,Accessories[i]->aid,s->iid,
|
sprintf(cBuf,"%-30s %4s %10u %3d %6s %4s %6s\n",s->hapName,s->type,Accessories[i]->aid,s->iid,
|
||||||
(void(*)())(s->*(&SpanService::update))!=(void(*)())(&SpanService::update)?"YES":"NO",
|
(void(*)())(s->*(&SpanService::update))!=(void(*)())(&SpanService::update)?"YES":"NO",
|
||||||
(void(*)())(s->*(&SpanService::loop))!=(void(*)())(&SpanService::loop)?"YES":"NO",
|
(void(*)())(s->*(&SpanService::loop))!=(void(*)())(&SpanService::loop)?"YES":"NO",
|
||||||
(void(*)(int,boolean))(s->*(&SpanService::button))!=(void(*)(int,boolean))(&SpanService::button)?"YES":"NO"
|
(void(*)(int,boolean))(s->*(&SpanService::button))!=(void(*)(int,boolean))(&SpanService::button)?"YES":"NO"
|
||||||
|
|
@ -767,22 +767,28 @@ void Span::prettyPrint(char *buf, int nsp){
|
||||||
|
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
|
|
||||||
SpanCharacteristic *Span::find(int aid, int iid){
|
SpanCharacteristic *Span::find(uint32_t aid, int iid){
|
||||||
|
|
||||||
if(aid<1 || aid>Accessories.size()) // aid out of range
|
int index=-1;
|
||||||
return(NULL);
|
for(int i=0;i<Accessories.size();i++){ // loop over all Accessories to find aid
|
||||||
|
if(Accessories[i]->aid==aid){ // if match, save index into Accessories array
|
||||||
aid--; // convert from aid to array index number
|
index=i;
|
||||||
|
break;
|
||||||
for(int i=0;i<Accessories[aid]->Services.size();i++){ // loop over all Services in this Accessory
|
|
||||||
for(int j=0;j<Accessories[aid]->Services[i]->Characteristics.size();j++){ // loop over all Characteristics in this Service
|
|
||||||
|
|
||||||
if(iid == Accessories[aid]->Services[i]->Characteristics[j]->iid) // if matching iid
|
|
||||||
return(Accessories[aid]->Services[i]->Characteristics[j]); // return pointer to Characteristic
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return(NULL);
|
if(index<0) // fail if no match on aid
|
||||||
|
return(NULL);
|
||||||
|
|
||||||
|
for(int i=0;i<Accessories[index]->Services.size();i++){ // loop over all Services in this Accessory
|
||||||
|
for(int j=0;j<Accessories[index]->Services[i]->Characteristics.size();j++){ // loop over all Characteristics in this Service
|
||||||
|
|
||||||
|
if(iid == Accessories[index]->Services[i]->Characteristics[j]->iid) // if matching iid
|
||||||
|
return(Accessories[index]->Services[i]->Characteristics[j]); // return pointer to Characteristic
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return(NULL); // fail if no match on iid
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
|
|
@ -828,7 +834,7 @@ int Span::updateCharacteristics(char *buf, SpanBuf *pObj){
|
||||||
t1=NULL;
|
t1=NULL;
|
||||||
char *t3;
|
char *t3;
|
||||||
if(!strcmp(t2,"aid") && (t3=strtok_r(t1,"}[]:, \"\t\n\r",&p2))){
|
if(!strcmp(t2,"aid") && (t3=strtok_r(t1,"}[]:, \"\t\n\r",&p2))){
|
||||||
pObj[nObj].aid=atoi(t3);
|
sscanf(t3,"%u",&pObj[nObj].aid);
|
||||||
okay|=1;
|
okay|=1;
|
||||||
} else
|
} else
|
||||||
if(!strcmp(t2,"iid") && (t3=strtok_r(t1,"}[]:, \"\t\n\r",&p2))){
|
if(!strcmp(t2,"iid") && (t3=strtok_r(t1,"}[]:, \"\t\n\r",&p2))){
|
||||||
|
|
@ -974,7 +980,7 @@ int Span::sprintfAttributes(SpanBuf *pObj, int nObj, char *cBuf){
|
||||||
nChars+=snprintf(cBuf,cBuf?64:0,"{\"characteristics\":[");
|
nChars+=snprintf(cBuf,cBuf?64:0,"{\"characteristics\":[");
|
||||||
|
|
||||||
for(int i=0;i<nObj;i++){
|
for(int i=0;i<nObj;i++){
|
||||||
nChars+=snprintf(cBuf?(cBuf+nChars):NULL,cBuf?128:0,"{\"aid\":%d,\"iid\":%d,\"status\":%d}",pObj[i].aid,pObj[i].iid,pObj[i].status);
|
nChars+=snprintf(cBuf?(cBuf+nChars):NULL,cBuf?128:0,"{\"aid\":%u,\"iid\":%d,\"status\":%d}",pObj[i].aid,pObj[i].iid,pObj[i].status);
|
||||||
if(i+1<nObj)
|
if(i+1<nObj)
|
||||||
nChars+=snprintf(cBuf?(cBuf+nChars):NULL,cBuf?64:0,",");
|
nChars+=snprintf(cBuf?(cBuf+nChars):NULL,cBuf?64:0,",");
|
||||||
}
|
}
|
||||||
|
|
@ -989,14 +995,15 @@ int Span::sprintfAttributes(SpanBuf *pObj, int nObj, char *cBuf){
|
||||||
int Span::sprintfAttributes(char **ids, int numIDs, int flags, char *cBuf){
|
int Span::sprintfAttributes(char **ids, int numIDs, int flags, char *cBuf){
|
||||||
|
|
||||||
int nChars=0;
|
int nChars=0;
|
||||||
int aid, iid;
|
uint32_t aid;
|
||||||
|
int iid;
|
||||||
|
|
||||||
SpanCharacteristic *Characteristics[numIDs];
|
SpanCharacteristic *Characteristics[numIDs];
|
||||||
StatusCode status[numIDs];
|
StatusCode status[numIDs];
|
||||||
boolean sFlag=false;
|
boolean sFlag=false;
|
||||||
|
|
||||||
for(int i=0;i<numIDs;i++){ // PASS 1: loop over all ids requested to check status codes - only errors are if characteristic not found, or not readable
|
for(int i=0;i<numIDs;i++){ // PASS 1: loop over all ids requested to check status codes - only errors are if characteristic not found, or not readable
|
||||||
sscanf(ids[i],"%d.%d",&aid,&iid); // parse aid and iid
|
sscanf(ids[i],"%u.%d",&aid,&iid); // parse aid and iid
|
||||||
Characteristics[i]=find(aid,iid); // find matching chararacteristic
|
Characteristics[i]=find(aid,iid); // find matching chararacteristic
|
||||||
|
|
||||||
if(Characteristics[i]){ // if found
|
if(Characteristics[i]){ // if found
|
||||||
|
|
@ -1020,8 +1027,8 @@ int Span::sprintfAttributes(char **ids, int numIDs, int flags, char *cBuf){
|
||||||
if(Characteristics[i]) // if found
|
if(Characteristics[i]) // if found
|
||||||
nChars+=Characteristics[i]->sprintfAttributes(cBuf?(cBuf+nChars):NULL,flags); // get JSON attributes for characteristic
|
nChars+=Characteristics[i]->sprintfAttributes(cBuf?(cBuf+nChars):NULL,flags); // get JSON attributes for characteristic
|
||||||
else{
|
else{
|
||||||
sscanf(ids[i],"%d.%d",&aid,&iid); // parse aid and iid
|
sscanf(ids[i],"%u.%d",&aid,&iid); // parse aid and iid
|
||||||
nChars+=snprintf(cBuf?(cBuf+nChars):NULL,cBuf?64:0,"{\"iid\":%d,\"aid\":%d}",iid,aid); // else create JSON attributes based on requested aid/iid
|
nChars+=snprintf(cBuf?(cBuf+nChars):NULL,cBuf?64:0,"{\"iid\":%d,\"aid\":%u}",iid,aid); // else create JSON attributes based on requested aid/iid
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sFlag){ // status flag is needed - overlay at end
|
if(sFlag){ // status flag is needed - overlay at end
|
||||||
|
|
@ -1043,7 +1050,7 @@ int Span::sprintfAttributes(char **ids, int numIDs, int flags, char *cBuf){
|
||||||
// SpanAccessory //
|
// SpanAccessory //
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
|
|
||||||
SpanAccessory::SpanAccessory(){
|
SpanAccessory::SpanAccessory(uint32_t aid){
|
||||||
|
|
||||||
if(!homeSpan.Accessories.empty()){
|
if(!homeSpan.Accessories.empty()){
|
||||||
|
|
||||||
|
|
@ -1054,9 +1061,13 @@ SpanAccessory::SpanAccessory(){
|
||||||
}
|
}
|
||||||
|
|
||||||
homeSpan.Accessories.push_back(this);
|
homeSpan.Accessories.push_back(this);
|
||||||
aid=homeSpan.Accessories.size();
|
|
||||||
|
|
||||||
homeSpan.configLog+="+Accessory-" + String(aid) + "\n";
|
if(aid==0)
|
||||||
|
this->aid=homeSpan.Accessories.size();
|
||||||
|
else
|
||||||
|
this->aid=aid;
|
||||||
|
|
||||||
|
homeSpan.configLog+="+Accessory-" + String(this->aid) + "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
|
|
@ -1093,7 +1104,7 @@ void SpanAccessory::validate(){
|
||||||
int SpanAccessory::sprintfAttributes(char *cBuf){
|
int SpanAccessory::sprintfAttributes(char *cBuf){
|
||||||
int nBytes=0;
|
int nBytes=0;
|
||||||
|
|
||||||
nBytes+=snprintf(cBuf,cBuf?64:0,"{\"aid\":%d,\"services\":[",aid);
|
nBytes+=snprintf(cBuf,cBuf?64:0,"{\"aid\":%u,\"services\":[",aid);
|
||||||
|
|
||||||
for(int i=0;i<Services.size();i++){
|
for(int i=0;i<Services.size();i++){
|
||||||
nBytes+=Services[i]->sprintfAttributes(cBuf?(cBuf+nBytes):NULL);
|
nBytes+=Services[i]->sprintfAttributes(cBuf?(cBuf+nBytes):NULL);
|
||||||
|
|
@ -1380,7 +1391,7 @@ int SpanCharacteristic::sprintfAttributes(char *cBuf, int flags){
|
||||||
}
|
}
|
||||||
|
|
||||||
if(flags&GET_AID)
|
if(flags&GET_AID)
|
||||||
nBytes+=snprintf(cBuf?(cBuf+nBytes):NULL,cBuf?64:0,",\"aid\":%d",aid);
|
nBytes+=snprintf(cBuf?(cBuf+nBytes):NULL,cBuf?64:0,",\"aid\":%u",aid);
|
||||||
|
|
||||||
if(flags&GET_EV)
|
if(flags&GET_EV)
|
||||||
nBytes+=snprintf(cBuf?(cBuf+nBytes):NULL,cBuf?64:0,",\"ev\":%s",ev[HAPClient::conNum]?"true":"false");
|
nBytes+=snprintf(cBuf?(cBuf+nBytes):NULL,cBuf?64:0,",\"ev\":%s",ev[HAPClient::conNum]?"true":"false");
|
||||||
|
|
|
||||||
|
|
@ -118,7 +118,7 @@ struct Span{
|
||||||
|
|
||||||
int sprintfAttributes(char *cBuf); // prints Attributes JSON database into buf, unless buf=NULL; return number of characters printed, excluding null terminator, even if buf=NULL
|
int sprintfAttributes(char *cBuf); // prints Attributes JSON database into buf, unless buf=NULL; return number of characters printed, excluding null terminator, even if buf=NULL
|
||||||
void prettyPrint(char *buf, int nsp=2); // print arbitrary JSON from buf to serial monitor, formatted with indentions of 'nsp' spaces
|
void prettyPrint(char *buf, int nsp=2); // print arbitrary JSON from buf to serial monitor, formatted with indentions of 'nsp' spaces
|
||||||
SpanCharacteristic *find(int aid, int iid); // return Characteristic with matching aid and iid (else NULL if not found)
|
SpanCharacteristic *find(uint32_t aid, int iid); // return Characteristic with matching aid and iid (else NULL if not found)
|
||||||
|
|
||||||
int countCharacteristics(char *buf); // return number of characteristic objects referenced in PUT /characteristics JSON request
|
int countCharacteristics(char *buf); // return number of characteristic objects referenced in PUT /characteristics JSON request
|
||||||
int updateCharacteristics(char *buf, SpanBuf *pObj); // parses PUT /characteristics JSON request 'buf into 'pObj' and updates referenced characteristics; returns 1 on success, 0 on fail
|
int updateCharacteristics(char *buf, SpanBuf *pObj); // parses PUT /characteristics JSON request 'buf into 'pObj' and updates referenced characteristics; returns 1 on success, 0 on fail
|
||||||
|
|
@ -142,11 +142,11 @@ struct Span{
|
||||||
|
|
||||||
struct SpanAccessory{
|
struct SpanAccessory{
|
||||||
|
|
||||||
int aid=0; // Accessory Instance ID (HAP Table 6-1)
|
uint32_t aid=0; // Accessory Instance ID (HAP Table 6-1)
|
||||||
int iidCount=0; // running count of iid to use for Services and Characteristics associated with this Accessory
|
int iidCount=0; // running count of iid to use for Services and Characteristics associated with this Accessory
|
||||||
vector<SpanService *> Services; // vector of pointers to all Services in this Accessory
|
vector<SpanService *> Services; // vector of pointers to all Services in this Accessory
|
||||||
|
|
||||||
SpanAccessory();
|
SpanAccessory(uint32_t aid=0);
|
||||||
|
|
||||||
int sprintfAttributes(char *cBuf); // prints Accessory JSON database into buf, unless buf=NULL; return number of characters printed, excluding null terminator, even if buf=NULL
|
int sprintfAttributes(char *cBuf); // prints Accessory JSON database into buf, unless buf=NULL; return number of characters printed, excluding null terminator, even if buf=NULL
|
||||||
void validate(); // error-checks Accessory
|
void validate(); // error-checks Accessory
|
||||||
|
|
@ -225,7 +225,7 @@ struct SpanCharacteristic{
|
||||||
SpanRange *range=NULL; // Characteristic min/max/step; NULL = default values (optional)
|
SpanRange *range=NULL; // Characteristic min/max/step; NULL = default values (optional)
|
||||||
boolean *ev; // Characteristic Event Notify Enable (per-connection)
|
boolean *ev; // Characteristic Event Notify Enable (per-connection)
|
||||||
|
|
||||||
int aid=0; // Accessory ID - passed through from Service containing this Characteristic
|
uint32_t aid=0; // Accessory ID - passed through from Service containing this Characteristic
|
||||||
boolean isUpdated=false; // set to true when new value has been requested by PUT /characteristic
|
boolean isUpdated=false; // set to true when new value has been requested by PUT /characteristic
|
||||||
unsigned long updateTime; // last time value was updated (in millis) either by PUT /characteristic OR by setVal()
|
unsigned long updateTime; // last time value was updated (in millis) either by PUT /characteristic OR by setVal()
|
||||||
UVal newValue; // the updated value requested by PUT /characteristic
|
UVal newValue; // the updated value requested by PUT /characteristic
|
||||||
|
|
@ -295,7 +295,7 @@ struct SpanRange{
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
|
|
||||||
struct SpanBuf{ // temporary storage buffer for use with putCharacteristicsURL() and checkTimedResets()
|
struct SpanBuf{ // temporary storage buffer for use with putCharacteristicsURL() and checkTimedResets()
|
||||||
int aid=0; // updated aid
|
uint32_t aid=0; // updated aid
|
||||||
int iid=0; // updated iid
|
int iid=0; // updated iid
|
||||||
char *val=NULL; // updated value (optional, though either at least 'val' or 'ev' must be specified)
|
char *val=NULL; // updated value (optional, though either at least 'val' or 'ev' must be specified)
|
||||||
char *ev=NULL; // updated event notification flag (optional, though either at least 'val' or 'ev' must be specified)
|
char *ev=NULL; // updated event notification flag (optional, though either at least 'val' or 'ev' must be specified)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue