diff --git a/src/Characteristics.h b/src/Characteristics.h new file mode 100644 index 0000000..38625fb --- /dev/null +++ b/src/Characteristics.h @@ -0,0 +1,170 @@ +/********************************************************************************* + * MIT License + * + * Copyright (c) 2020-2021 Gregg E. Berman + * + * https://github.com/HomeSpan/HomeSpan + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + ********************************************************************************/ + +////////////////////////////////////////// +// HAP CHARACTERISTICS (HAP Chapter 9) // +////////////////////////////////////////// + +enum PERMS{ // create bitflags based on HAP Table 6-4 + PR=1, + PW=2, + EV=4, + AA=8, + TW=16, + HD=32, + WR=64, + NV=128 // this is a non-HAP flag used to specify that no value should be provided (should be a HAP flag!) +}; + +enum FORMAT { // HAP Table 6-5 + BOOL, + UINT8, + UINT16, + UINT32, + UINT64, + INT, + FLOAT, + STRING +}; + +/////////////////////////////// + +struct HapChar { + const char *type; + const char *hapName; + PERMS perms; + FORMAT format; +}; + +/////////////////////////////// + +#define HAPCHAR(hapName,type,perms,format) HapChar hapName {#type,#hapName,(PERMS)(perms),format} + +struct HapCharacteristics { + + HAPCHAR( Active, B0, PW+PR+EV, UINT8 ); + HAPCHAR( AirQuality, 95, PR+EV, UINT8 ); + HAPCHAR( BatteryLevel, 68, PR+EV, UINT8 ); + HAPCHAR( Brightness, 8, PR+PW+EV, INT ); + HAPCHAR( CarbonMonoxideLevel, 90, PR+EV, FLOAT ); + HAPCHAR( CarbonMonoxidePeakLevel, 91, PR+EV, FLOAT ); + HAPCHAR( CarbonDioxideDetected, 92, PR+EV, UINT8 ); + HAPCHAR( CarbonDioxideLevel, 93, PR+EV, FLOAT ); + HAPCHAR( CarbonDioxidePeakLevel, 94, PR+EV, FLOAT ); + HAPCHAR( CarbonMonoxideDetected, 69, PR+EV, UINT8 ); + HAPCHAR( ChargingState, 8F, PR+EV, UINT8 ); + HAPCHAR( CoolingThresholdTemperature, D, PR+PW+EV, FLOAT ); + HAPCHAR( ColorTemperature, CE, PR+PW+EV, UINT32 ); + HAPCHAR( ContactSensorState, 6A, PR+EV, UINT8 ); + HAPCHAR( CurrentAmbientLightLevel, 6B, PR+EV, FLOAT ); + HAPCHAR( CurrentHorizontalTiltAngle, 6C, PR+EV, INT ); + HAPCHAR( CurrentAirPurifierState, A9, PR+EV, UINT8 ); + HAPCHAR( CurrentSlatState, AA, PR+EV, UINT8 ); + HAPCHAR( CurrentPosition, 6D, PR+EV, UINT8 ); + HAPCHAR( CurrentVerticalTiltAngle, 6E, PR+EV, INT ); + HAPCHAR( CurrentHumidifierDehumidifierState, B3, PR+EV, UINT8 ); + HAPCHAR( CurrentDoorState, E, PR+EV, UINT8 ); + HAPCHAR( CurrentFanState, AF, PR+EV, UINT8 ); + HAPCHAR( CurrentHeatingCoolingState, F, PR+EV, UINT8 ); + HAPCHAR( CurrentHeaterCoolerState, B1, PR+EV, UINT8 ); + HAPCHAR( CurrentRelativeHumidity, 10, PR+EV, FLOAT ); + HAPCHAR( CurrentTemperature, 11, PR+EV, FLOAT ); + HAPCHAR( CurrentTiltAngle, C1, PR+EV, INT ); + HAPCHAR( FilterLifeLevel, AB, PR+EV, FLOAT ); + HAPCHAR( FilterChangeIndication, AC, PR+EV, UINT8 ); + HAPCHAR( FirmwareRevision, 52, PR, STRING ); + HAPCHAR( HardwareRevision, 53, PR, STRING ); + HAPCHAR( HeatingThresholdTemperature, 12, PR+PW+EV, FLOAT ); + HAPCHAR( HoldPosition, 6F, PW, BOOL ); + HAPCHAR( Hue, 13, PR+PW+EV, FLOAT ); + HAPCHAR( Identify, 14, PW, BOOL ); + HAPCHAR( InUse, D2, PR+EV, UINT8 ); + HAPCHAR( IsConfigured, D6, PR+EV, UINT8 ); + HAPCHAR( LeakDetected, 70, PR+EV, UINT8 ); + HAPCHAR( LockCurrentState, 1D, PR+EV, UINT8 ); + HAPCHAR( LockPhysicalControls, A7, PW+PR+EV, UINT8 ); + HAPCHAR( LockTargetState, 1E, PW+PR+EV, UINT8 ); + HAPCHAR( Manufacturer, 20, PR, STRING ); + HAPCHAR( Model, 21, PR, STRING ); + HAPCHAR( MotionDetected, 22, PR+EV, BOOL ); + HAPCHAR( Mute, 11A, PW+PR+EV, BOOL ); + HAPCHAR( Name, 23, PR, STRING ); + HAPCHAR( NitrogenDioxideDensity, C4, PR+EV, FLOAT ); + HAPCHAR( ObstructionDetected, 24, PR+EV, BOOL ); + HAPCHAR( PM25Density, C6, PR+EV, FLOAT ); + HAPCHAR( OccupancyDetected, 71, PR+EV, UINT8 ); + HAPCHAR( OutletInUse, 26, PR+EV, BOOL ); + HAPCHAR( On, 25, PR+PW+EV, BOOL ); + HAPCHAR( OzoneDensity, C3, PR+EV, FLOAT ); + HAPCHAR( PM10Density, C7, PR+EV, FLOAT ); + HAPCHAR( PositionState, 72, PR+EV, UINT8 ); + HAPCHAR( ProgramMode, D1, PR+EV, UINT8 ); + HAPCHAR( ProgrammableSwitchEvent, 73, PR+EV+NV, UINT8 ); + HAPCHAR( RelativeHumidityDehumidifierThreshold, C9, PR+PW+EV, FLOAT ); + HAPCHAR( RelativeHumidityHumidifierThreshold, CA, PR+PW+EV, FLOAT ); + HAPCHAR( RemainingDuration, D4, PR+EV, UINT32 ); + HAPCHAR( ResetFilterIndication, AD, PW, UINT8 ); + HAPCHAR( RotationDirection, 28, PR+PW+EV, INT ); + HAPCHAR( RotationSpeed, 29, PR+PW+EV, FLOAT ); + HAPCHAR( Saturation, 2F, PR+PW+EV, FLOAT ); + HAPCHAR( SecuritySystemAlarmType, 8E, PR+EV, UINT8 ); + HAPCHAR( SecuritySystemCurrentState, 66, PR+EV, UINT8 ); + HAPCHAR( SecuritySystemTargetState, 67, PW+PR+EV, UINT8 ); + HAPCHAR( SerialNumber, 30, PR, STRING ); + HAPCHAR( ServiceLabelIndex, CB, PR, UINT8 ); + HAPCHAR( ServiceLabelNamespace, CD, PR, UINT8 ); + HAPCHAR( SlatType, C0, PR, UINT8 ); + HAPCHAR( SmokeDetected, 76, PR+EV, UINT8 ); + HAPCHAR( StatusActive, 75, PR+EV, BOOL ); + HAPCHAR( StatusFault, 77, PR+EV, UINT8 ); + HAPCHAR( StatusJammed, 78, PR+EV, UINT8 ); + HAPCHAR( StatusLowBattery, 79, PR+EV, UINT8 ); + HAPCHAR( StatusTampered, 7A, PR+EV, UINT8 ); + HAPCHAR( SulphurDioxideDensity, C5, PR+EV, FLOAT ); + HAPCHAR( SwingMode, B6, PR+EV+PW, UINT8 ); + HAPCHAR( TargetAirPurifierState, A8, PW+PR+EV, UINT8 ); + HAPCHAR( TargetFanState, BF, PW+PR+EV, UINT8 ); + HAPCHAR( TargetTiltAngle, C2, PW+PR+EV, INT ); + HAPCHAR( TargetHeaterCoolerState, B2, PW+PR+EV, UINT8 ); + HAPCHAR( SetDuration, D3, PW+PR+EV, UINT32 ); + HAPCHAR( TargetHorizontalTiltAngle, 7B, PW+PR+EV, INT ); + HAPCHAR( TargetHumidifierDehumidifierState, B4, PW+PR+EV, UINT8 ); + HAPCHAR( TargetPosition, 7C, PW+PR+EV, UINT8 ); + HAPCHAR( TargetDoorState, 32, PW+PR+EV, UINT8 ); + HAPCHAR( TargetHeatingCoolingState, 33, PW+PR+EV, UINT8 ); + HAPCHAR( TargetRelativeHumidity, 34, PW+PR+EV, FLOAT ); + HAPCHAR( TargetTemperature, 35, PW+PR+EV, FLOAT ); + HAPCHAR( TemperatureDisplayUnits, 36, PW+PR+EV, UINT8 ); + HAPCHAR( TargetVerticalTiltAngle, 7D, PW+PR+EV, INT ); + HAPCHAR( ValveType, D5, PR+EV, UINT8 ); + HAPCHAR( Version, 37, PR, STRING ); + HAPCHAR( VOCDensity, C8, PR+EV, FLOAT ); + HAPCHAR( Volume, 119, PW+PR+EV, UINT8 ); + HAPCHAR( WaterLevel, B5, PR+EV, FLOAT ); +}; + +extern HapCharacteristics hapChars; diff --git a/src/HAPConstants.h b/src/HAPConstants.h index 3e23ffc..77bd183 100644 --- a/src/HAPConstants.h +++ b/src/HAPConstants.h @@ -86,130 +86,3 @@ enum class StatusCode { InvalidValue=-70410, TBD=-1 // status To-Be-Determined (TBD) once service.update() called - internal use only }; - -/////////////////////////////// - -struct HapCharType { - const char *id; - const char *name; - uint8_t perms; -}; - -/////////////////////////////// - -#define HAPCHAR(name,id,perms) HapCharType name {#id,#name,perms} - -struct HapCharList { - - enum { // create bitflags based on HAP Table 6-4 - PR=1, - PW=2, - EV=4, - AA=8, - TW=16, - HD=32, - WR=64, - NV=128 - }; - - HAPCHAR( Active, B0, PW+PR+EV ); - HAPCHAR( AirQuality, 95, PR+EV ); - HAPCHAR( BatteryLevel, 68, PR+EV ); - HAPCHAR( Brightness, 8, PR+PW+EV ); - HAPCHAR( CarbonMonoxideLevel, 90, PR+EV ); - HAPCHAR( CarbonMonoxidePeakLevel, 91, PR+EV ); - HAPCHAR( CarbonDioxideDetected, 92, PR+EV ); - HAPCHAR( CarbonDioxideLevel, 93, PR+EV ); - HAPCHAR( CarbonDioxidePeakLevel, 94, PR+EV ); - HAPCHAR( CarbonMonoxideDetected, 69, PR+EV ); - HAPCHAR( ChargingState, 8F, PR+EV ); - HAPCHAR( CoolingThresholdTemperature, D, PR+PW+EV ); - HAPCHAR( ColorTemperature, CE, PR+PW+EV ); - HAPCHAR( ContactSensorState, 6A, PR+EV ); - HAPCHAR( CurrentAmbientLightLevel, 6B, PR+EV ); - HAPCHAR( CurrentHorizontalTiltAngle, 6C, PR+EV ); - HAPCHAR( CurrentAirPurifierState, A9, PR+EV ); - HAPCHAR( CurrentSlatState, AA, PR+EV ); - HAPCHAR( CurrentPosition, 6D, PR+EV ); - HAPCHAR( CurrentVerticalTiltAngle, 6E, PR+EV ); - HAPCHAR( CurrentHumidifierDehumidifierState, B3, PR+EV ); - HAPCHAR( CurrentDoorState, E, PR+EV ); - HAPCHAR( CurrentFanState, AF, PR+EV ); - HAPCHAR( CurrentHeatingCoolingState, F, PR+EV ); - HAPCHAR( CurrentHeaterCoolerState, B1, PR+EV ); - HAPCHAR( CurrentRelativeHumidity, 10, PR+EV ); - HAPCHAR( CurrentTemperature, 11, PR+EV ); - HAPCHAR( CurrentTiltAngle, C1, PR+EV ); - HAPCHAR( FilterLifeLevel, AB, PR+EV ); - HAPCHAR( FilterChangeIndication, AC, PR+EV ); - HAPCHAR( FirmwareRevision, 52, PR ); - HAPCHAR( HardwareRevision, 53, PR ); - HAPCHAR( HeatingThresholdTemperature, 12, PR+PW+EV ); - HAPCHAR( HoldPosition, 6F, PW ); - HAPCHAR( Hue, 13, PR+PW+EV ); - HAPCHAR( Identify, 14, PW ); - HAPCHAR( InUse, D2, PR+EV ); - HAPCHAR( IsConfigured, D6, PR+EV ); - HAPCHAR( LeakDetected, 70, PR+EV ); - HAPCHAR( LockCurrentState, 1D, PR+EV ); - HAPCHAR( LockPhysicalControls, A7, PW+PR+EV ); - HAPCHAR( LockTargetState, 1E, PW+PR+EV ); - HAPCHAR( Manufacturer, 20, PR ); - HAPCHAR( Model, 21, PR ); - HAPCHAR( MotionDetected, 22, PR+EV ); - HAPCHAR( Mute, 11A, PW+PR+EV ); - HAPCHAR( Name, 23, PR ); - HAPCHAR( NitrogenDioxideDensity, C4, PR+EV ); - HAPCHAR( ObstructionDetected, 24, PR+EV ); - HAPCHAR( PM25Density, C6, PR+EV ); - HAPCHAR( OccupancyDetected, 71, PR+EV ); - HAPCHAR( OutletInUse, 26, PR+EV ); - HAPCHAR( On, 25, PR+PW+EV ); - HAPCHAR( OzoneDensity, C3, PR+EV ); - HAPCHAR( PM10Density, C7, PR+EV ); - HAPCHAR( PositionState, 72, PR+EV ); - HAPCHAR( ProgramMode, D1, PR+EV ); - HAPCHAR( ProgrammableSwitchEvent, 73, PR+EV+NV ); // NV = flag to indicate that HomeSpan should always return a null value, as required by HAP for this Characteristic - HAPCHAR( RelativeHumidityDehumidifierThreshold, C9, PR+PW+EV ); - HAPCHAR( RelativeHumidityHumidifierThreshold, CA, PR+PW+EV ); - HAPCHAR( RemainingDuration, D4, PR+EV ); - HAPCHAR( ResetFilterIndication, AD, PW ); - HAPCHAR( RotationDirection, 28, PR+PW+EV ); - HAPCHAR( RotationSpeed, 29, PR+PW+EV ); - HAPCHAR( Saturation , 2F, PR+PW+EV ); - HAPCHAR( SecuritySystemAlarmType , 8E, PR+EV ); - HAPCHAR( SecuritySystemCurrentState , 66, PR+EV ); - HAPCHAR( SecuritySystemTargetState , 67, PW+PR+EV ); - HAPCHAR( SerialNumber, 30, PR ); - HAPCHAR( ServiceLabelIndex, CB, PR ); - HAPCHAR( ServiceLabelNamespace, CD, PR ); - HAPCHAR( SlatType, C0, PR ); - HAPCHAR( SmokeDetected, 76, PR+EV ); - HAPCHAR( StatusActive, 75, PR+EV ); - HAPCHAR( StatusFault, 77, PR+EV ); - HAPCHAR( StatusJammed, 78, PR+EV ); - HAPCHAR( StatusLowBattery, 79, PR+EV ); - HAPCHAR( StatusTampered, 7A, PR+EV ); - HAPCHAR( SulphurDioxideDensity, C5, PR+EV ); - HAPCHAR( SwingMode, B6, PR+EV+PW ); - HAPCHAR( TargetAirPurifierState, A8, PW+PR+EV ); - HAPCHAR( TargetFanState, BF, PW+PR+EV ); - HAPCHAR( TargetTiltAngle, C2, PW+PR+EV ); - HAPCHAR( TargetHeaterCoolerState, B2, PW+PR+EV ); - HAPCHAR( SetDuration, D3, PW+PR+EV ); - HAPCHAR( TargetHorizontalTiltAngle, 7B, PW+PR+EV ); - HAPCHAR( TargetHumidifierDehumidifierState, B4, PW+PR+EV ); - HAPCHAR( TargetPosition, 7C, PW+PR+EV ); - HAPCHAR( TargetDoorState, 32, PW+PR+EV ); - HAPCHAR( TargetHeatingCoolingState, 33, PW+PR+EV ); - HAPCHAR( TargetRelativeHumidity, 34, PW+PR+EV ); - HAPCHAR( TargetTemperature, 35, PW+PR+EV ); - HAPCHAR( TemperatureDisplayUnits, 36, PW+PR+EV ); - HAPCHAR( TargetVerticalTiltAngle, 7D, PW+PR+EV ); - HAPCHAR( ValveType, D5, PR+EV ); - HAPCHAR( Version, 37, PR ); - HAPCHAR( VOCDensity, C8, PR+EV ); - HAPCHAR( Volume, 119, PW+PR+EV ); - HAPCHAR( WaterLevel, B5, PR+EV ); - -}; diff --git a/src/HomeSpan.cpp b/src/HomeSpan.cpp index 4e01328..cdab560 100644 --- a/src/HomeSpan.cpp +++ b/src/HomeSpan.cpp @@ -39,6 +39,7 @@ using namespace Utils; HAPClient **hap; // HAP Client structure containing HTTP client connections, parsing routines, and state variables (global-scoped variable) Span homeSpan; // HAP Attributes database and all related control functions for this Accessory (global-scoped variable) +HapCharacteristics hapChars; // Instantiation of all HAP Characteristics (used to create SpanCharacteristics) /////////////////////////////// // Span // @@ -1203,10 +1204,10 @@ int Span::sprintfAttributes(char **ids, int numIDs, int flags, char *cBuf){ for(int i=0;iperms&SpanCharacteristic::PR){ // if permissions allow reading + if(Characteristics[i]->perms&PERMS::PR){ // if permissions allow reading status[i]=StatusCode::OK; // always set status to OK (since no actual reading of device is needed) } else { Characteristics[i]=NULL; @@ -1440,10 +1441,10 @@ void SpanService::validate(){ for(int i=0;iid,Characteristics[j]->type); + valid=!strcmp(req[i]->type,Characteristics[j]->type); if(!valid){ - homeSpan.configLog+=" !Characteristic " + String(req[i]->name); + homeSpan.configLog+=" !Characteristic " + String(req[i]->hapName); homeSpan.configLog+=" *** ERROR! Required Characteristic for this Service not found. ***\n"; homeSpan.nFatalErrors++; } @@ -1454,10 +1455,11 @@ void SpanService::validate(){ // SpanCharacteristic // /////////////////////////////// -SpanCharacteristic::SpanCharacteristic(const char *type, uint8_t perms, const char *hapName){ - this->type=type; - this->perms=perms; - this->hapName=hapName; +SpanCharacteristic::SpanCharacteristic(HapChar *hapChar){ + type=hapChar->type; + perms=hapChar->perms; + hapName=hapChar->hapName; + format=hapChar->format; homeSpan.configLog+="---->Characteristic " + String(hapName); @@ -1478,10 +1480,10 @@ SpanCharacteristic::SpanCharacteristic(const char *type, uint8_t perms, const ch boolean valid=false; for(int i=0; !valid && iServices.back()->req.size(); i++) - valid=!strcmp(type,homeSpan.Accessories.back()->Services.back()->req[i]->id); + valid=!strcmp(type,homeSpan.Accessories.back()->Services.back()->req[i]->type); for(int i=0; !valid && iServices.back()->opt.size(); i++) - valid=!strcmp(type,homeSpan.Accessories.back()->Services.back()->opt[i]->id); + valid=!strcmp(type,homeSpan.Accessories.back()->Services.back()->opt[i]->type); if(!valid){ homeSpan.configLog+=" *** ERROR! Service does not support this Characteristic. ***"; @@ -1500,64 +1502,7 @@ SpanCharacteristic::SpanCharacteristic(const char *type, uint8_t perms, const ch homeSpan.Accessories.back()->Services.back()->Characteristics.push_back(this); - homeSpan.configLog+="\n"; - -} - -/////////////////////////////// - -SpanCharacteristic::SpanCharacteristic(const char *type, uint8_t perms, boolean value, const char *hapName) : SpanCharacteristic(type, perms, hapName) { - this->format=BOOL; - this->value.BOOL=value; -} - -/////////////////////////////// - -SpanCharacteristic::SpanCharacteristic(const char *type, uint8_t perms, int32_t value, const char *hapName) : SpanCharacteristic(type, perms, hapName) { - this->format=INT; - this->value.INT=value; -} - -/////////////////////////////// - -SpanCharacteristic::SpanCharacteristic(const char *type, uint8_t perms, uint8_t value, const char *hapName) : SpanCharacteristic(type, perms, hapName) { - this->format=UINT8; - this->value.UINT8=value; -} - -/////////////////////////////// - -SpanCharacteristic::SpanCharacteristic(const char *type, uint8_t perms, uint16_t value, const char *hapName) : SpanCharacteristic(type, perms, hapName) { - this->format=UINT16; - this->value.UINT16=value; -} - -/////////////////////////////// - -SpanCharacteristic::SpanCharacteristic(const char *type, uint8_t perms, uint32_t value, const char *hapName) : SpanCharacteristic(type, perms, hapName) { - this->format=UINT32; - this->value.UINT32=value; -} - -/////////////////////////////// - -SpanCharacteristic::SpanCharacteristic(const char *type, uint8_t perms, uint64_t value, const char *hapName) : SpanCharacteristic(type, perms, hapName) { - this->format=UINT64; - this->value.UINT64=value; -} - -/////////////////////////////// - -SpanCharacteristic::SpanCharacteristic(const char *type, uint8_t perms, double value, const char *hapName) : SpanCharacteristic(type, perms, hapName) { - this->format=FLOAT; - this->value.FLOAT=value; -} - -/////////////////////////////// - -SpanCharacteristic::SpanCharacteristic(const char *type, uint8_t perms, const char* value, const char *hapName) : SpanCharacteristic(type, perms, hapName) { - this->format=STRING; - this->value.STRING=value; + homeSpan.configLog+="\n"; } /////////////////////////////// diff --git a/src/HomeSpan.h b/src/HomeSpan.h index 7e23842..fefbfb9 100644 --- a/src/HomeSpan.h +++ b/src/HomeSpan.h @@ -39,6 +39,7 @@ #include "Network.h" #include "HAPConstants.h" #include "HapQR.h" +#include "Characteristics.h" using std::vector; using std::unordered_map; @@ -54,17 +55,6 @@ enum { GET_ALL=255 }; -enum FORMAT { // HAP Table 6-5 - BOOL, - UINT8, - UINT16, - UINT32, - UINT64, - INT, - FLOAT, - STRING -}; - union UVal { boolean BOOL; uint8_t UINT8; @@ -222,8 +212,6 @@ struct Span{ vector PushButtons; // vector of pointer to all PushButtons unordered_map TimedWrites; // map of timed-write PIDs and Alarm Times (based on TTLs) - HapCharList chr; // list of all HAP Characteristics - void begin(Category catID=DEFAULT_CATEGORY, const char *displayName=DEFAULT_DISPLAY_NAME, const char *hostNameBase=DEFAULT_HOST_NAME, @@ -289,8 +277,8 @@ struct SpanService{ boolean hidden=false; // optional property indicating service is hidden boolean primary=false; // optional property indicating service is primary vector Characteristics; // vector of pointers to all Characteristics in this Service - vector req; // vector of pointers to all required HAP Characteristic Types for this Service - vector opt; // vector of pointers to all optional HAP Characteristic Types for this Service + vector req; // vector of pointers to all required HAP Characteristic Types for this Service + vector opt; // vector of pointers to all optional HAP Characteristic Types for this Service vector linkedServices; // vector of pointers to any optional linked Services SpanService(const char *type, const char *hapName); @@ -311,17 +299,6 @@ struct SpanService{ struct SpanCharacteristic{ - enum { // create bitflags based on HAP Table 6-4 - PR=1, - PW=2, - EV=4, - AA=8, - TW=16, - HD=32, - WR=64, - NV=128 - }; - int iid=0; // Instance ID (HAP Table 6-3) const char *type; // Characteristic Type const char *hapName; // HAP Name @@ -338,15 +315,11 @@ struct SpanCharacteristic{ UVal newValue; // the updated value requested by PUT /characteristic SpanService *service=NULL; // pointer to Service containing this Characteristic - SpanCharacteristic(const char *type, uint8_t perms, const char *hapName); - SpanCharacteristic(const char *type, uint8_t perms, boolean value, const char *hapName); - SpanCharacteristic(const char *type, uint8_t perms, uint8_t value, const char *hapName); - SpanCharacteristic(const char *type, uint8_t perms, uint16_t value, const char *hapName); - SpanCharacteristic(const char *type, uint8_t perms, uint32_t value, const char *hapName); - SpanCharacteristic(const char *type, uint8_t perms, uint64_t value, const char *hapName); - SpanCharacteristic(const char *type, uint8_t perms, int32_t value, const char *hapName); - SpanCharacteristic(const char *type, uint8_t perms, double value, const char *hapName); - SpanCharacteristic(const char *type, uint8_t perms, const char* value, const char *hapName); + SpanCharacteristic(HapChar *hapChar); // contructor + + template void init(T val){ + value.set(format,val); + } 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.) diff --git a/src/Services.h b/src/Services.h index 8b19cc0..f28516e 100644 --- a/src/Services.h +++ b/src/Services.h @@ -24,15 +24,15 @@ * SOFTWARE. * ********************************************************************************/ - + /////////////////////////////////// // SPAN SERVICES (HAP Chapter 8) // /////////////////////////////////// // Macros to define vectors of required and optional characteristics for each Span Service structure -#define REQ(name) req.push_back(&homeSpan.chr.name) -#define OPT(name) opt.push_back(&homeSpan.chr.name) +#define REQ(HAPCHAR) req.push_back(&hapChars.HAPCHAR) +#define OPT(HAPCHAR) opt.push_back(&hapChars.HAPCHAR) namespace Service { @@ -381,109 +381,116 @@ namespace Service { // SPAN CHARACTERISTICS (HAP Chapter 9) // ////////////////////////////////////////// -// Macro to define Span Characteristic structures based on name of HAP Characteristic (see HAPConstants.h), its type (e.g. int, double) and its default value +// Macro to define Span Characteristic structures based on name of HAP Characteristic, default value, and mix/max value (not applicable for STRING) -#define CREATE_CHAR(CHR,TYPE,DEFVAL) struct CHR : SpanCharacteristic { CHR(TYPE value=DEFVAL) : SpanCharacteristic{homeSpan.chr.CHR.id, homeSpan.chr.CHR.perms,(TYPE)value, homeSpan.chr.CHR.name}{} } +#define CREATE_CHAR_FLOAT(HAPCHAR,DEFVAL) struct HAPCHAR : SpanCharacteristic { HAPCHAR(double val=DEFVAL) : SpanCharacteristic {&hapChars.HAPCHAR} { init(val); } }; +#define CREATE_CHAR_INT(HAPCHAR,DEFVAL) struct HAPCHAR : SpanCharacteristic { HAPCHAR(int val=DEFVAL) : SpanCharacteristic {&hapChars.HAPCHAR} { init(val); } }; +#define CREATE_CHAR_UINT8(HAPCHAR,DEFVAL) struct HAPCHAR : SpanCharacteristic { HAPCHAR(uint8_t val=DEFVAL) : SpanCharacteristic {&hapChars.HAPCHAR} { init(val); } }; +#define CREATE_CHAR_UINT16(HAPCHAR,DEFVAL) struct HAPCHAR : SpanCharacteristic { HAPCHAR(uint16_t val=DEFVAL) : SpanCharacteristic {&hapChars.HAPCHAR} { init(val); } }; +#define CREATE_CHAR_UINT32(HAPCHAR,DEFVAL) struct HAPCHAR : SpanCharacteristic { HAPCHAR(uint32_t val=DEFVAL) : SpanCharacteristic {&hapChars.HAPCHAR} { init(val); } }; +#define CREATE_CHAR_UINT64(HAPCHAR,DEFVAL) struct HAPCHAR : SpanCharacteristic { HAPCHAR(uint64_t val=DEFVAL) : SpanCharacteristic {&hapChars.HAPCHAR} { init(val); } }; +#define CREATE_CHAR_BOOL(HAPCHAR,DEFVAL) struct HAPCHAR : SpanCharacteristic { HAPCHAR(boolean val=DEFVAL) : SpanCharacteristic {&hapChars.HAPCHAR} { init(val); } }; +#define CREATE_CHAR_STRING(HAPCHAR,DEFVAL) struct HAPCHAR : SpanCharacteristic { HAPCHAR(const char *val=DEFVAL) : SpanCharacteristic {&hapChars.HAPCHAR} { value.STRING=val; } }; namespace Characteristic { - - CREATE_CHAR(Active,uint8_t,0); - CREATE_CHAR(AirQuality,uint8_t,0); - CREATE_CHAR(BatteryLevel,uint8_t,0); - CREATE_CHAR(Brightness,int,0); - CREATE_CHAR(CarbonMonoxideLevel,double,0); - CREATE_CHAR(CarbonMonoxidePeakLevel,double,0); - CREATE_CHAR(CarbonMonoxideDetected,uint8_t,0); - CREATE_CHAR(CarbonDioxideLevel,double,0); - CREATE_CHAR(CarbonDioxidePeakLevel,double,0); - CREATE_CHAR(CarbonDioxideDetected,uint8_t,0); - CREATE_CHAR(ChargingState,uint8_t,0); - CREATE_CHAR(CoolingThresholdTemperature,double,10); - CREATE_CHAR(ColorTemperature,uint32_t,200); - CREATE_CHAR(ContactSensorState,uint8_t,1); - CREATE_CHAR(CurrentAmbientLightLevel,double,1); - CREATE_CHAR(CurrentHorizontalTiltAngle,int,0); - CREATE_CHAR(CurrentAirPurifierState,uint8_t,1); - CREATE_CHAR(CurrentSlatState,uint8_t,0); - CREATE_CHAR(CurrentPosition,uint8_t,0); - CREATE_CHAR(CurrentVerticalTiltAngle,int,0); - CREATE_CHAR(CurrentHumidifierDehumidifierState,uint8_t,1); - CREATE_CHAR(CurrentDoorState,uint8_t,1); - CREATE_CHAR(CurrentFanState,uint8_t,1); - CREATE_CHAR(CurrentHeatingCoolingState,uint8_t,0); - CREATE_CHAR(CurrentHeaterCoolerState,uint8_t,1); - CREATE_CHAR(CurrentRelativeHumidity,double,0); - CREATE_CHAR(CurrentTemperature,double,0); - CREATE_CHAR(CurrentTiltAngle,int,0); - CREATE_CHAR(FilterLifeLevel,double,0); - CREATE_CHAR(FilterChangeIndication,uint8_t,0); - CREATE_CHAR(FirmwareRevision,const char *,"1.0.0"); - CREATE_CHAR(HardwareRevision,const char *,"1.0.0"); - CREATE_CHAR(HeatingThresholdTemperature,double,16); - CREATE_CHAR(HoldPosition,boolean,false); - CREATE_CHAR(Hue,double,0); - CREATE_CHAR(Identify,boolean,false); - CREATE_CHAR(InUse,uint8_t,0); - CREATE_CHAR(IsConfigured,uint8_t,0); - CREATE_CHAR(LeakDetected,uint8_t,0); - CREATE_CHAR(LockCurrentState,uint8_t,0); - CREATE_CHAR(LockPhysicalControls,uint8_t,0); - CREATE_CHAR(LockTargetState,uint8_t,0); - CREATE_CHAR(Manufacturer,const char *,"HomeSpan"); - CREATE_CHAR(Model,const char *,"HomeSpan-ESP32"); - CREATE_CHAR(MotionDetected,boolean,false); - CREATE_CHAR(Mute,boolean,false); - CREATE_CHAR(Name,const char *,"unnamed"); - CREATE_CHAR(NitrogenDioxideDensity,double,0); - CREATE_CHAR(ObstructionDetected,boolean,false); - CREATE_CHAR(PM25Density,double,0); - CREATE_CHAR(OccupancyDetected,uint8_t,0); - CREATE_CHAR(OutletInUse,boolean,false); - CREATE_CHAR(On,boolean,false); - CREATE_CHAR(OzoneDensity,double,0); - CREATE_CHAR(PM10Density,double,0); - CREATE_CHAR(PositionState,uint8_t,2); - CREATE_CHAR(ProgramMode,uint8_t,0); - CREATE_CHAR(ProgrammableSwitchEvent,uint8_t,0); - CREATE_CHAR(RelativeHumidityDehumidifierThreshold,double,50); - CREATE_CHAR(RelativeHumidityHumidifierThreshold,double,50); - CREATE_CHAR(RemainingDuration,uint32_t,60); - CREATE_CHAR(ResetFilterIndication,uint8_t,0); - CREATE_CHAR(RotationDirection,int,0); - CREATE_CHAR(RotationSpeed,double,0); - CREATE_CHAR(Saturation,double,0); - CREATE_CHAR(SecuritySystemAlarmType,uint8_t,0); - CREATE_CHAR(SecuritySystemCurrentState,uint8_t,3); - CREATE_CHAR(SecuritySystemTargetState,uint8_t,3); - CREATE_CHAR(SerialNumber,const char *,"HS-12345"); - CREATE_CHAR(ServiceLabelIndex,uint8_t,1); - CREATE_CHAR(ServiceLabelNamespace,uint8_t,1); - CREATE_CHAR(SlatType,uint8_t,0); - CREATE_CHAR(SmokeDetected,uint8_t,0); - CREATE_CHAR(StatusActive,boolean,true); - CREATE_CHAR(StatusFault,uint8_t,0); - CREATE_CHAR(StatusJammed,uint8_t,0); - CREATE_CHAR(StatusLowBattery,uint8_t,0); - CREATE_CHAR(StatusTampered,uint8_t,0); - CREATE_CHAR(SulphurDioxideDensity,double,0); - CREATE_CHAR(SwingMode,uint8_t,0); - CREATE_CHAR(TargetAirPurifierState,uint8_t,1); - CREATE_CHAR(TargetFanState,uint8_t,1); - CREATE_CHAR(TargetTiltAngle,int,0); - CREATE_CHAR(SetDuration,uint32_t,60); - CREATE_CHAR(TargetHorizontalTiltAngle,int,0); - CREATE_CHAR(TargetHumidifierDehumidifierState,uint8_t,0); - CREATE_CHAR(TargetPosition,uint8_t,0); - CREATE_CHAR(TargetDoorState,uint8_t,1); - CREATE_CHAR(TargetHeatingCoolingState,uint8_t,0); - CREATE_CHAR(TargetRelativeHumidity,double,0); - CREATE_CHAR(TargetTemperature,double,16); - CREATE_CHAR(TemperatureDisplayUnits,uint8_t,0); - CREATE_CHAR(TargetVerticalTiltAngle,int,0); - CREATE_CHAR(ValveType,uint8_t,0); - CREATE_CHAR(Version,const char *,"1.0.0"); - CREATE_CHAR(VOCDensity,double,0); - CREATE_CHAR(Volume,uint8_t,0); - CREATE_CHAR(WaterLevel,double,0); + CREATE_CHAR_UINT8(Active,0); + CREATE_CHAR_UINT8(AirQuality,0); + CREATE_CHAR_UINT8(BatteryLevel,0); + CREATE_CHAR_INT(Brightness,0); + CREATE_CHAR_FLOAT(CarbonMonoxideLevel,0); + CREATE_CHAR_FLOAT(CarbonMonoxidePeakLevel,0); + CREATE_CHAR_UINT8(CarbonMonoxideDetected,0); + CREATE_CHAR_FLOAT(CarbonDioxideLevel,0); + CREATE_CHAR_FLOAT(CarbonDioxidePeakLevel,0); + CREATE_CHAR_UINT8(CarbonDioxideDetected,0); + CREATE_CHAR_UINT8(ChargingState,0); + CREATE_CHAR_FLOAT(CoolingThresholdTemperature,10); + CREATE_CHAR_UINT32(ColorTemperature,200); + CREATE_CHAR_UINT8(ContactSensorState,1); + CREATE_CHAR_FLOAT(CurrentAmbientLightLevel,1); + CREATE_CHAR_INT(CurrentHorizontalTiltAngle,0); + CREATE_CHAR_UINT8(CurrentAirPurifierState,1); + CREATE_CHAR_UINT8(CurrentSlatState,0); + CREATE_CHAR_UINT8(CurrentPosition,0); + CREATE_CHAR_INT(CurrentVerticalTiltAngle,0); + CREATE_CHAR_UINT8(CurrentHumidifierDehumidifierState,1); + CREATE_CHAR_UINT8(CurrentDoorState,1); + CREATE_CHAR_UINT8(CurrentFanState,1); + CREATE_CHAR_UINT8(CurrentHeatingCoolingState,0); + CREATE_CHAR_UINT8(CurrentHeaterCoolerState,1); + CREATE_CHAR_FLOAT(CurrentRelativeHumidity,0); + CREATE_CHAR_FLOAT(CurrentTemperature,0); + CREATE_CHAR_INT(CurrentTiltAngle,0); + CREATE_CHAR_FLOAT(FilterLifeLevel,0); + CREATE_CHAR_UINT8(FilterChangeIndication,0); + CREATE_CHAR_STRING(FirmwareRevision,"1.0.0"); + CREATE_CHAR_STRING(HardwareRevision,"1.0.0"); + CREATE_CHAR_FLOAT(HeatingThresholdTemperature,16); + CREATE_CHAR_BOOL(HoldPosition,false); + CREATE_CHAR_FLOAT(Hue,0); + CREATE_CHAR_BOOL(Identify,false); + CREATE_CHAR_UINT8(InUse,0); + CREATE_CHAR_UINT8(IsConfigured,0); + CREATE_CHAR_UINT8(LeakDetected,0); + CREATE_CHAR_UINT8(LockCurrentState,0); + CREATE_CHAR_UINT8(LockPhysicalControls,0); + CREATE_CHAR_UINT8(LockTargetState,0); + CREATE_CHAR_STRING(Manufacturer,"HomeSpan"); + CREATE_CHAR_STRING(Model,"HomeSpan-ESP32"); + CREATE_CHAR_BOOL(MotionDetected,false); + CREATE_CHAR_BOOL(Mute,false); + CREATE_CHAR_STRING(Name,"unnamed"); + CREATE_CHAR_FLOAT(NitrogenDioxideDensity,0); + CREATE_CHAR_BOOL(ObstructionDetected,false); + CREATE_CHAR_FLOAT(PM25Density,0); + CREATE_CHAR_UINT8(OccupancyDetected,0); + CREATE_CHAR_BOOL(OutletInUse,false); + CREATE_CHAR_BOOL(On,false); + CREATE_CHAR_FLOAT(OzoneDensity,0); + CREATE_CHAR_FLOAT(PM10Density,0); + CREATE_CHAR_UINT8(PositionState,2); + CREATE_CHAR_UINT8(ProgramMode,0); + CREATE_CHAR_UINT8(ProgrammableSwitchEvent,0); + CREATE_CHAR_FLOAT(RelativeHumidityDehumidifierThreshold,50); + CREATE_CHAR_FLOAT(RelativeHumidityHumidifierThreshold,50); + CREATE_CHAR_UINT32(RemainingDuration,60); + CREATE_CHAR_UINT8(ResetFilterIndication,0); + CREATE_CHAR_INT(RotationDirection,0); + CREATE_CHAR_FLOAT(RotationSpeed,0); + CREATE_CHAR_FLOAT(Saturation,0); + CREATE_CHAR_UINT8(SecuritySystemAlarmType,0); + CREATE_CHAR_UINT8(SecuritySystemCurrentState,3); + CREATE_CHAR_UINT8(SecuritySystemTargetState,3); + CREATE_CHAR_STRING(SerialNumber,"HS-12345"); + CREATE_CHAR_UINT8(ServiceLabelIndex,1); + CREATE_CHAR_UINT8(ServiceLabelNamespace,1); + CREATE_CHAR_UINT8(SlatType,0); + CREATE_CHAR_UINT8(SmokeDetected,0); + CREATE_CHAR_BOOL(StatusActive,true); + CREATE_CHAR_UINT8(StatusFault,0); + CREATE_CHAR_UINT8(StatusJammed,0); + CREATE_CHAR_UINT8(StatusLowBattery,0); + CREATE_CHAR_UINT8(StatusTampered,0); + CREATE_CHAR_FLOAT(SulphurDioxideDensity,0); + CREATE_CHAR_UINT8(SwingMode,0); + CREATE_CHAR_UINT8(TargetAirPurifierState,1); + CREATE_CHAR_UINT8(TargetFanState,1); + CREATE_CHAR_INT(TargetTiltAngle,0); + CREATE_CHAR_UINT32(SetDuration,60); + CREATE_CHAR_INT(TargetHorizontalTiltAngle,0); + CREATE_CHAR_UINT8(TargetHumidifierDehumidifierState,0); + CREATE_CHAR_UINT8(TargetPosition,0); + CREATE_CHAR_UINT8(TargetDoorState,1); + CREATE_CHAR_UINT8(TargetHeatingCoolingState,0); + CREATE_CHAR_FLOAT(TargetRelativeHumidity,0); + CREATE_CHAR_FLOAT(TargetTemperature,16); + CREATE_CHAR_UINT8(TemperatureDisplayUnits,0); + CREATE_CHAR_INT(TargetVerticalTiltAngle,0); + CREATE_CHAR_UINT8(ValveType,0); + CREATE_CHAR_STRING(Version,"1.0.0"); + CREATE_CHAR_FLOAT(VOCDensity,0); + CREATE_CHAR_UINT8(Volume,0); + CREATE_CHAR_FLOAT(WaterLevel,0); + }