Extended functionality of setValidValues() to allow INT, UINT8, UINT16, and UINT32 Characteristics

This commit is contained in:
Gregg 2023-02-25 15:07:02 -06:00
parent ae7d4ddcb8
commit 09063fb7dc
4 changed files with 33 additions and 59 deletions

View File

@ -39,7 +39,7 @@
void setup() { void setup() {
// If the only Service defined in the FIRST Accessory of a mult-Accessory device is the required Accessory Information Service, // If the only Service defined in the FIRST Accessory of a multi-Accessory device is the required Accessory Information Service,
// the device is said to be configured as a "Bridge". Historically there may have been a number of functional differences between bridge // the device is said to be configured as a "Bridge". Historically there may have been a number of functional differences between bridge
// devices and non-bridge devices, but since iOS 15, it's not obvious there are any differences in functionality, with two exceptions: // devices and non-bridge devices, but since iOS 15, it's not obvious there are any differences in functionality, with two exceptions:

View File

@ -1977,17 +1977,28 @@ unsigned long SpanCharacteristic::timeVal(){
/////////////////////////////// ///////////////////////////////
SpanCharacteristic *SpanCharacteristic::setValidValues(int n, ...){ SpanCharacteristic *SpanCharacteristic::setValidValues(int n, ...){
if(format!=UINT8){
setValidValuesError=true;
return(this);
}
String s="["; String s="[";
va_list vl; va_list vl;
va_start(vl,n); va_start(vl,n);
for(int i=0;i<n;i++){ for(int i=0;i<n;i++){
s+=(uint8_t)va_arg(vl,int); switch(format){
case FORMAT::UINT8:
s+=(uint8_t)va_arg(vl,uint32_t);
break;
case FORMAT::UINT16:
s+=(uint16_t)va_arg(vl,uint32_t);
break;
case FORMAT::UINT32:
s+=(uint32_t)va_arg(vl,uint32_t);
break;
case FORMAT::INT:
s+=(int)va_arg(vl,uint32_t);
break;
default:
setValidValuesError=true;
return(this);
}
if(i!=n-1) if(i!=n-1)
s+=","; s+=",";
} }

View File

@ -743,7 +743,7 @@ class SpanCharacteristic{
boolean updated(){return(isUpdated);} // returns isUpdated boolean updated(){return(isUpdated);} // returns isUpdated
unsigned long timeVal(); // returns time elapsed (in millis) since value was last updated unsigned long timeVal(); // returns time elapsed (in millis) since value was last updated
SpanCharacteristic *setValidValues(int n, ...); // sets a list of 'n' valid values allowed for a Characteristic and returns pointer to self. Only applicable if format=uint8 SpanCharacteristic *setValidValues(int n, ...); // sets a list of 'n' valid values allowed for a Characteristic and returns pointer to self. Only applicable if format=INT, UINT8, UINT16, or UINT32
template <typename A, typename B, typename S=int> SpanCharacteristic *setRange(A min, B max, S step=0){ template <typename A, typename B, typename S=int> SpanCharacteristic *setRange(A min, B max, S step=0){

View File

@ -30,70 +30,33 @@
#include "HomeSpan.h" #include "HomeSpan.h"
struct RemoteTempSensor : Service::TemperatureSensor { CUSTOM_CHAR(CharFloat, 00000001-0001-0001-0001-46637266EA00, PR+PW+EV, FLOAT, 0, 0, 100, false);
CUSTOM_CHAR(CharUInt8, 00000009-0001-0001-0001-46637266EA00, PR+PW+EV, UINT8, 0, 0, 100, false);
SpanCharacteristic *temp; CUSTOM_CHAR(CharUInt16, 00000016-0001-0001-0001-46637266EA00, PR+PW+EV, UINT16, 0, 0, 100, false);
SpanCharacteristic *fault; CUSTOM_CHAR(CharUInt32, 00000032-0001-0001-0001-46637266EA00, PR+PW+EV, UINT32, 0, 0, 100, false);
SpanPoint *remoteTemp; CUSTOM_CHAR(CharInt, 00000002-0001-0001-0001-46637266EA00, PR+PW+EV, INT, 0, 0, 100, false);
const char *name;
float temperature;
RemoteTempSensor(const char *name, const char*macAddress, boolean is8266=false) : Service::TemperatureSensor(){
this->name=name;
temp=new Characteristic::CurrentTemperature(-10.0); // set initial temperature
temp->setRange(-50,100); // expand temperature range to allow negative values
fault=new Characteristic::StatusFault(1); // set initial state = fault
remoteTemp=new SpanPoint(macAddress,0,sizeof(float),1,is8266); // create a SpanPoint with send size=0 and receive size=sizeof(float)
} // end constructor
void loop(){
if(remoteTemp->get(&temperature)){ // if there is data from the remote sensor
temp->setVal(temperature); // update temperature
fault->setVal(0); // clear fault
LOG1("Sensor %s update: Temperature=%0.2f\n",name,temperature*9/5+32);
} else if(remoteTemp->time()>60000 && !fault->getVal()){ // else if it has been a while since last update (60 seconds), and there is no current fault
fault->setVal(1); // set fault state
LOG1("Sensor %s update: FAULT\n",name);
}
} // loop
};
////////////////////////////////////// //////////////////////////////////////
void setup() { void setup() {
Serial.begin(115200); Serial.begin(115200);
homeSpan.setLogLevel(1); homeSpan.setLogLevel(1);
homeSpan.begin(Category::Bridges,"Sensor Hub"); homeSpan.begin(Category::Other,"HomeSpan Test");
new SpanAccessory(); new SpanAccessory();
new Service::AccessoryInformation(); new Service::AccessoryInformation();
new Characteristic::Identify(); new Characteristic::Identify();
new Service::LightBulb();
new SpanAccessory(); new Characteristic::On();
new Service::AccessoryInformation();
new Characteristic::Identify();
new Characteristic::Name("Indoor Temp");
new RemoteTempSensor("Device 1","AC:67:B2:77:42:20"); // pass MAC Address of Remote Device
new SpanAccessory();
new Service::AccessoryInformation();
new Characteristic::Identify();
new Characteristic::Name("Outdoor Temp");
new RemoteTempSensor("Device 2","BC:FF:4D:40:8E:71",true); // pass MAC Address of Remote Device with 8266 flag set (will use AP MAC Address)
(new Characteristic::CharFloat())->setValidValues(5,0,1,2,6,7,8);
(new Characteristic::CharUInt8())->setValidValues(5,0,1,2,6,7,8);
(new Characteristic::CharUInt16())->setValidValues(5,0,1<<8,1<<16,0xFFFFFFFF,-1);
(new Characteristic::CharUInt32())->setValidValues(5,0,1<<8,1<<16,0xFFFFFFFF,-1);
(new Characteristic::CharInt())->setValidValues(5,0,255,2000000000,-2000000000,-1);
} // end of setup() } // end of setup()