Refactored setVal() to use a template
Ensures robustness and is fully backwards compatible. User does NOT have to specify a template parameter, as the compiler determines this from the setVal() argument itself. Allows for any numeric type to be properly mapped to correct HAP format for the Characteristic. This change is also needed to prepare for the refactoring of SpanRange, the addition of UVals to store HAP min/max, and new error-checking of min/max limits within setVal.
This commit is contained in:
parent
433e1cd59a
commit
f591735deb
103
src/HomeSpan.cpp
103
src/HomeSpan.cpp
|
|
@ -1737,109 +1737,6 @@ StatusCode SpanCharacteristic::loadUpdate(char *val, char *ev){
|
||||||
|
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
|
|
||||||
void SpanCharacteristic::setVal(int val){
|
|
||||||
|
|
||||||
switch(format){
|
|
||||||
|
|
||||||
case BOOL:
|
|
||||||
value.BOOL=(boolean)val;
|
|
||||||
newValue.BOOL=(boolean)val;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case INT:
|
|
||||||
value.INT=(int)val;
|
|
||||||
newValue.INT=(int)val;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case UINT8:
|
|
||||||
value.UINT8=(uint8_t)val;
|
|
||||||
newValue.INT=(int)val;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case UINT16:
|
|
||||||
value.UINT16=(uint16_t)val;
|
|
||||||
newValue.UINT16=(uint16_t)val;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case UINT32:
|
|
||||||
value.UINT32=(uint32_t)val;
|
|
||||||
newValue.UINT32=(uint32_t)val;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case UINT64:
|
|
||||||
value.UINT64=(uint64_t)val;
|
|
||||||
newValue.UINT64=(uint64_t)val;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FLOAT:
|
|
||||||
value.FLOAT=(double)val;
|
|
||||||
newValue.FLOAT=(double)val;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////
|
|
||||||
|
|
||||||
void SpanCharacteristic::setVal(uint32_t val){
|
|
||||||
|
|
||||||
value.UINT32=(uint32_t)val;
|
|
||||||
newValue.UINT32=(uint32_t)val;
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////
|
|
||||||
|
|
||||||
void SpanCharacteristic::setVal(uint64_t val){
|
|
||||||
|
|
||||||
value.UINT64=(uint64_t)val;
|
|
||||||
newValue.UINT64=(uint64_t)val;
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////
|
|
||||||
|
|
||||||
void SpanCharacteristic::setVal(double val){
|
|
||||||
|
|
||||||
value.FLOAT=(double)val;
|
|
||||||
newValue.FLOAT=(double)val;
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////
|
|
||||||
|
|
||||||
unsigned long SpanCharacteristic::timeVal(){
|
unsigned long SpanCharacteristic::timeVal(){
|
||||||
|
|
||||||
return(homeSpan.snapTime-updateTime);
|
return(homeSpan.snapTime-updateTime);
|
||||||
|
|
|
||||||
175
src/HomeSpan.h
175
src/HomeSpan.h
|
|
@ -54,6 +54,64 @@ enum {
|
||||||
GET_ALL=255
|
GET_ALL=255
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum FORMAT { // HAP Table 6-5
|
||||||
|
BOOL,
|
||||||
|
UINT8,
|
||||||
|
UINT16,
|
||||||
|
UINT32,
|
||||||
|
UINT64,
|
||||||
|
INT,
|
||||||
|
FLOAT,
|
||||||
|
STRING
|
||||||
|
};
|
||||||
|
|
||||||
|
union UVal {
|
||||||
|
boolean BOOL;
|
||||||
|
uint8_t UINT8;
|
||||||
|
uint16_t UINT16;
|
||||||
|
uint32_t UINT32;
|
||||||
|
uint64_t UINT64;
|
||||||
|
int32_t INT;
|
||||||
|
double FLOAT;
|
||||||
|
const char *STRING;
|
||||||
|
|
||||||
|
template <typename T> void set(FORMAT fmt, T val){
|
||||||
|
|
||||||
|
switch(fmt){
|
||||||
|
|
||||||
|
case FORMAT::BOOL:
|
||||||
|
BOOL=(boolean)val;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FORMAT::INT:
|
||||||
|
INT=(int)val;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FORMAT::UINT8:
|
||||||
|
UINT8=(uint8_t)val;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FORMAT::UINT16:
|
||||||
|
UINT16=(uint16_t)val;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FORMAT::UINT32:
|
||||||
|
UINT32=(uint32_t)val;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FORMAT::UINT64:
|
||||||
|
UINT64=(uint64_t)val;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FORMAT::FLOAT:
|
||||||
|
FLOAT=(double)val;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////
|
||||||
|
|
||||||
// Forward-Declarations
|
// Forward-Declarations
|
||||||
|
|
||||||
struct Span;
|
struct Span;
|
||||||
|
|
@ -64,6 +122,8 @@ struct SpanRange;
|
||||||
struct SpanBuf;
|
struct SpanBuf;
|
||||||
struct SpanButton;
|
struct SpanButton;
|
||||||
|
|
||||||
|
extern Span homeSpan;
|
||||||
|
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
|
|
||||||
struct SpanConfig {
|
struct SpanConfig {
|
||||||
|
|
@ -73,6 +133,17 @@ struct SpanConfig {
|
||||||
|
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
|
|
||||||
|
struct SpanBuf{ // temporary storage buffer for use with putCharacteristicsURL() and checkTimedResets()
|
||||||
|
uint32_t aid=0; // updated aid
|
||||||
|
int iid=0; // updated iid
|
||||||
|
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)
|
||||||
|
StatusCode status; // return status (HAP Table 6-11)
|
||||||
|
SpanCharacteristic *characteristic=NULL; // Characteristic to update (NULL if not found)
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////
|
||||||
|
|
||||||
struct Span{
|
struct Span{
|
||||||
|
|
||||||
const char *displayName; // display name for this device - broadcast as part of Bonjour MDNS
|
const char *displayName; // display name for this device - broadcast as part of Bonjour MDNS
|
||||||
|
|
@ -218,28 +289,6 @@ struct SpanCharacteristic{
|
||||||
NV=128
|
NV=128
|
||||||
};
|
};
|
||||||
|
|
||||||
enum FORMAT { // HAP Table 6-5
|
|
||||||
BOOL=0,
|
|
||||||
UINT8=1,
|
|
||||||
UINT16=2,
|
|
||||||
UINT32=3,
|
|
||||||
UINT64=4,
|
|
||||||
INT=5,
|
|
||||||
FLOAT=6,
|
|
||||||
STRING=7
|
|
||||||
};
|
|
||||||
|
|
||||||
union UVal {
|
|
||||||
boolean BOOL;
|
|
||||||
uint8_t UINT8;
|
|
||||||
uint16_t UINT16;
|
|
||||||
uint32_t UINT32;
|
|
||||||
uint64_t UINT64;
|
|
||||||
int32_t INT;
|
|
||||||
double FLOAT;
|
|
||||||
const char *STRING;
|
|
||||||
};
|
|
||||||
|
|
||||||
int iid=0; // Instance ID (HAP Table 6-3)
|
int iid=0; // Instance ID (HAP Table 6-3)
|
||||||
const char *type; // Characteristic Type
|
const char *type; // Characteristic Type
|
||||||
const char *hapName; // HAP Name
|
const char *hapName; // HAP Name
|
||||||
|
|
@ -269,43 +318,52 @@ struct SpanCharacteristic{
|
||||||
int sprintfAttributes(char *cBuf, int flags); // prints Characteristic JSON records into buf, according to flags mask; return number of characters printed, excluding null terminator
|
int sprintfAttributes(char *cBuf, int flags); // prints Characteristic JSON records into buf, according to flags mask; return number of characters printed, excluding null terminator
|
||||||
StatusCode loadUpdate(char *val, char *ev); // load updated val/ev from PUT /characteristic JSON request. Return intiial HAP status code (checks to see if characteristic is found, is writable, etc.)
|
StatusCode loadUpdate(char *val, char *ev); // load updated val/ev from PUT /characteristic JSON request. Return intiial HAP status code (checks to see if characteristic is found, is writable, etc.)
|
||||||
|
|
||||||
|
boolean updated(){return(isUpdated);} // returns isUpdated
|
||||||
|
unsigned long timeVal(); // returns time elapsed (in millis) since value was last updated
|
||||||
|
|
||||||
template <class T=int> T getVal(){return(getValue<T>(value));} // returns UVal value
|
template <class T=int> T getVal(){return(getValue<T>(value));} // returns UVal value
|
||||||
template <class T=int> T getNewVal(){return(getValue<T>(newValue));} // returns UVal newValue
|
template <class T=int> T getNewVal(){return(getValue<T>(newValue));} // returns UVal newValue
|
||||||
template <class T> T getValue(UVal v); // returns UVal v
|
|
||||||
|
|
||||||
void setVal(uint64_t value); // sets value of UVal value for UINT64 Characteristic when parameter type is uint64_t
|
template <class T> T getValue(UVal v){
|
||||||
void setVal(uint32_t value); // sets value of UVal value for UINT32 Characteristic when parameter type is uint32_t
|
|
||||||
void setVal(double value); // sets value of UVal value for FLOAT Characteristic when parameter type is float or double
|
|
||||||
void setVal(int value); // sets value of UVal value for ANY Characteristic (except char *) when parameter type does not exactly match uint64_t, uint32_t, double, or float
|
|
||||||
|
|
||||||
boolean updated(){return(isUpdated);} // returns isUpdated
|
switch(format){
|
||||||
unsigned long timeVal(); // returns time elapsed (in millis) since value was last updated
|
case BOOL:
|
||||||
|
return((T) v.BOOL);
|
||||||
|
case INT:
|
||||||
|
return((T) v.INT);
|
||||||
|
case UINT8:
|
||||||
|
return((T) v.UINT8);
|
||||||
|
case UINT16:
|
||||||
|
return((T) v.UINT16);
|
||||||
|
case UINT32:
|
||||||
|
return((T) v.UINT32);
|
||||||
|
case UINT64:
|
||||||
|
return((T) v.UINT64);
|
||||||
|
case FLOAT:
|
||||||
|
return((T) v.FLOAT);
|
||||||
|
case STRING:
|
||||||
|
Serial.print("*** ERROR: Can't use getVal() or getNewVal() for string Characteristics.\n\n");
|
||||||
|
return(0);
|
||||||
|
|
||||||
};
|
} // switch
|
||||||
|
|
||||||
///////////////////////////////
|
} // getValue
|
||||||
|
|
||||||
template <class T> T SpanCharacteristic::getValue(UVal v){
|
template <typename T> void setVal(T val){
|
||||||
|
|
||||||
switch(format){
|
value.set(format, val);
|
||||||
case BOOL:
|
newValue.set(format, val);
|
||||||
return((T) v.BOOL);
|
|
||||||
case INT:
|
updateTime=homeSpan.snapTime;
|
||||||
return((T) v.INT);
|
|
||||||
case UINT8:
|
SpanBuf sb; // create SpanBuf object
|
||||||
return((T) v.UINT8);
|
sb.characteristic=this; // set characteristic
|
||||||
case UINT16:
|
sb.status=StatusCode::OK; // set status
|
||||||
return((T) v.UINT16);
|
char dummy[]="";
|
||||||
case UINT32:
|
sb.val=dummy; // set dummy "val" so that sprintfNotify knows to consider this "update"
|
||||||
return((T) v.UINT32);
|
homeSpan.Notifications.push_back(sb); // store SpanBuf in Notifications vector
|
||||||
case UINT64:
|
|
||||||
return((T) v.UINT64);
|
} // setValue
|
||||||
case FLOAT:
|
|
||||||
return((T) v.FLOAT);
|
|
||||||
case STRING:
|
|
||||||
Serial.print("*** ERROR: Can't use getVal() or getNewVal() for string Characteristics.\n\n");
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -321,17 +379,6 @@ struct SpanRange{
|
||||||
|
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
|
|
||||||
struct SpanBuf{ // temporary storage buffer for use with putCharacteristicsURL() and checkTimedResets()
|
|
||||||
uint32_t aid=0; // updated aid
|
|
||||||
int iid=0; // updated iid
|
|
||||||
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)
|
|
||||||
StatusCode status; // return status (HAP Table 6-11)
|
|
||||||
SpanCharacteristic *characteristic=NULL; // Characteristic to update (NULL if not found)
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////
|
|
||||||
|
|
||||||
struct SpanButton{
|
struct SpanButton{
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
|
@ -352,10 +399,6 @@ struct SpanButton{
|
||||||
};
|
};
|
||||||
|
|
||||||
/////////////////////////////////////////////////
|
/////////////////////////////////////////////////
|
||||||
// Extern Variables
|
|
||||||
|
|
||||||
extern Span homeSpan;
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include "Services.h"
|
#include "Services.h"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue