Eliminated ServiceType from Library and Example 11

Next up - update Examples 12+ to delete ServiceType
This commit is contained in:
Gregg 2020-09-27 15:56:48 -05:00
parent 814d751e71
commit fa8c5934ea
7 changed files with 51 additions and 84 deletions

View File

@ -33,31 +33,12 @@ void setup() {
// lightbulb or a fan?
// HomeKit determines which icon to show on the combined tile according to what is considered the Primary Service of the Accessory.
// This can be set directly in HomeSpan for any given Service by setting its "ServiceType". ServiceType is an optional argument to the
// Service object constructor. Note that as an optional argument, it needs to be placed last.
// There are three possible ServiceTypes: Regular, Primary, and Hidden, as defined in the HomeSpan library Settings.h file.
// ServiceType::Regular is used to specifiy a service that has no special settings. This is the default used if you don't specify any
// ServiceType. In all our previous examples, ServiceType::Regular has been implied.
// Specifying ServiceType::Primary for a Service tells HomeSpan to set the "primary" attribute for that Service to "true" in the attribute
// database. HomeKit will use this information to deermine which icon to display for a combined tile. HomeKit will also list the Primary Service
// first when you click a combined tile to open its controls.
// HomeKit will also list the Primary Service first when you click a combined tile to open its controls.
// Specifying ServiceType::Hidden for a Service tells HomeSpan to set the "hidden" attribute for that Service to "true". This tells HomeKit
// to completely hide the controls for this service in the HomeKit interface. We've not used this feature in any of our examples. It's generally
// only needed to create an "internal" Service to be used by other Services, but not by the actual end-user.
// As noted, ServiceType is an optional argument for the new Service constructor, so ServiceType::Primary can simply be added as the last
// argument whenever we create a new Service to indicate it's the Primary one for the Accessory. But this won't work for the derived Services
// we created, such as DEV_LED or DEV_DimmableLED. This is because when we created those derived classes we did not include an optional
// ServiceType argument in the constructor. Doing so is very easy - you just need to modify the constructors, as shown for DEV_LED and
// DEV_DimmableLED in the the DEV_LED.h file. We even modified the constructor for DEV_Identify in DEV_Identify.h so we can specify when
// it should be considered the Primary Service. There is a good use case for that as we'll see below. Please see DEV_Identify.h and DEV_LED.h
// for exactly how these new constructors are formulated.
// Once we've modified our constructors accordingly, we're ready to specify which is the Primary Service for any given Accessory, as shown below.
// First, we need to initialize HomeSpan and define our Bridge Accessory as in the previous examples:
// A Service can be set to Primary with the setPrimary() method. The easiest way to do this is by "chaining" setPrimary() to the
// end of a new Service when first instantiated. See below for examples of how to do this.
// To begin, we first initialize HomeSpan and define our Bridge Accessory as in the previous examples:
Serial.begin(115200);
@ -76,7 +57,7 @@ void setup() {
new SpanAccessory();
new DEV_Identify("Ceiling Fan #1","HomeSpan","123-ABC","20mA LED","0.9",0);
new DEV_DimmableLED(0,17,ServiceType::Primary); // Here we specify DEV_DimmableLED as the Primary Service
(new DEV_DimmableLED(0,17))->setPrimary(); // Here we specify DEV_DimmableLED as the Primary Service by "chaining" setPrimary() to the pointer return by new. Note parentheses!
new Service::Fan();
new Characteristic::Active();
new Characteristic::RotationDirection();
@ -85,7 +66,7 @@ void setup() {
new SpanAccessory();
new DEV_Identify("Ceiling Fan #2","HomeSpan","123-ABC","20mA LED","0.9",0);
new DEV_DimmableLED(0,17);
new Service::Fan(ServiceType::Primary); // Here we specify the Fan as the Primary Service
(new Service::Fan())->setPrimary(); // Here we specify the Fan as the Primary Service. Again, note how we encapsulated the "new" command in parentheses, then chained setPrimary()
new Characteristic::Active();
new Characteristic::RotationDirection();
new Characteristic::RotationSpeed(0);
@ -118,7 +99,7 @@ void setup() {
new Characteristic::Name("Main Light"); // Here we create a name for the Dimmable LED
new DEV_LED(16);
new Characteristic::Name("Night Light"); // Here we create a name for the On/Off LED
new Service::Fan(ServiceType::Primary);
(new Service::Fan())->setPrimary();
new Characteristic::Active();
new Characteristic::RotationDirection();
new Characteristic::RotationSpeed(0);
@ -141,7 +122,7 @@ void setup() {
// This is easily done by specifying DEV_Identify as the Primary Service, instead of Fan, as follows:
new SpanAccessory();
new DEV_Identify("Ceiling Fan #4","HomeSpan","123-ABC","20mA LED","0.9",0,ServiceType::Primary); // specify DEV_Identify as the Primary Service
(new DEV_Identify("Ceiling Fan #4","HomeSpan","123-ABC","20mA LED","0.9",0))->setPrimary(); // specify DEV_Identify as the Primary Service
new DEV_DimmableLED(0,17);
new Characteristic::Name("Main Light");
new DEV_LED(16);
@ -152,14 +133,14 @@ void setup() {
new Characteristic::RotationSpeed(0);
new Characteristic::Name("Fan");
// HomeKit now shows the name "Ceiling Fan #3" for the combined tile AND it still shows the individual names for each control when you click open the tile.
// HomeKit now shows the name "Ceiling Fan #4" for the combined tile AND it still shows the individual names for each control when you click open the tile.
// The only downside to this configuration is that since the Fan is no longer specified as the Primary Service, the main icon on the combined tile now shows
// as a lightbulb, instead of the fan. HomeKit documentation is not clear on how the main icon is chosen under these circumstances, but I've found
// that changing the order of Services as they are instantiated can impact the icon. Here is the same example as above, but with the Fan
// instantiated as the first opertional Service, ahead of the Main Light and Night Night:
// instantiated as the first operational Service, ahead of the Main Light and Night Night:
new SpanAccessory();
new DEV_Identify("Ceiling Fan #5","HomeSpan","123-ABC","20mA LED","0.9",0,ServiceType::Primary); // specify DEV_Identify as the Primary Service
(new DEV_Identify("Ceiling Fan #5","HomeSpan","123-ABC","20mA LED","0.9",0))->setPrimary(); // specify DEV_Identify as the Primary Service
new Service::Fan();
new Characteristic::Active();
new Characteristic::RotationDirection();

View File

@ -7,10 +7,8 @@ struct DEV_Identify : Service::AccessoryInformation {
int nBlinks; // number of times to blink built-in LED in identify routine
SpanCharacteristic *identify; // reference to the Identify Characteristic
// NEW! modified constructor() method to include optional ServiceType argument
DEV_Identify(char *name, char *manu, char *sn, char *model, char *version, int nBlinks, ServiceType sType=ServiceType::Regular) : Service::AccessoryInformation(sType){
DEV_Identify(char *name, char *manu, char *sn, char *model, char *version, int nBlinks) : Service::AccessoryInformation(){
new Characteristic::Name(name); // create all the required Characteristics with values set based on above arguments
new Characteristic::Manufacturer(manu);

View File

@ -12,7 +12,7 @@ struct DEV_LED : Service::LightBulb { // ON/OFF LED
int ledPin; // pin number defined for this LED
SpanCharacteristic *power; // reference to the On Characteristic
DEV_LED(int ledPin, ServiceType sType=ServiceType::Regular) : Service::LightBulb(sType){ // NEW! modified constructor() method to include optional ServiceType argument
DEV_LED(int ledPin) : Service::LightBulb(){
power=new Characteristic::On();
this->ledPin=ledPin;
@ -51,7 +51,7 @@ struct DEV_DimmableLED : Service::LightBulb { // Dimmable LED
SpanCharacteristic *power; // reference to the On Characteristic
SpanCharacteristic *level; // reference to the Brightness Characteristic
DEV_DimmableLED(int channel, int ledPin, ServiceType sType=ServiceType::Regular) : Service::LightBulb(sType){ // // NEW! modified constructor() method
DEV_DimmableLED(int channel, int ledPin) : Service::LightBulb(){
power=new Characteristic::On();

View File

@ -915,11 +915,9 @@ int SpanAccessory::sprintfAttributes(char *cBuf){
// SpanService //
///////////////////////////////
SpanService::SpanService(const char *type, ServiceType mod){
SpanService::SpanService(const char *type){
this->type=type;
hidden=(mod==ServiceType::Hidden);
primary=(mod==ServiceType::Primary);
if(homeSpan.Accessories.empty()){
Serial.print("*** FATAL ERROR: Can't create new Service without a defined Accessory. Program halted!\n\n");

View File

@ -113,7 +113,7 @@ struct SpanService{
boolean primary=false; // optional property indicating service is primary
vector<SpanCharacteristic *> Characteristics; // vector of pointers to all Characteristics in this Service
SpanService(const char *type, ServiceType mod=ServiceType::Regular);
SpanService(const char *type);
SpanService *setPrimary(); // sets the Service Type to be primary and returns pointer to self
SpanService *setHidden(); // sets the Service Type to be hidden and returns pointer to self

View File

@ -5,73 +5,73 @@
namespace Service {
struct AccessoryInformation : SpanService { AccessoryInformation(ServiceType mod=ServiceType::Regular) : SpanService{"3E", mod}{} };
struct AccessoryInformation : SpanService { AccessoryInformation() : SpanService{"3E"}{} };
struct AirPurifier : SpanService { AirPurifier(ServiceType mod=ServiceType::Regular) : SpanService{"BB", mod}{} };
struct AirPurifier : SpanService { AirPurifier() : SpanService{"BB"}{} };
struct AirQualitySensor : SpanService { AirQualitySensor(ServiceType mod=ServiceType::Regular) : SpanService{"8D", mod}{} };
struct AirQualitySensor : SpanService { AirQualitySensor() : SpanService{"8D"}{} };
struct BatteryService : SpanService { BatteryService(ServiceType mod=ServiceType::Regular) : SpanService{"96", mod}{} };
struct BatteryService : SpanService { BatteryService() : SpanService{"96"}{} };
struct CarbonDioxideSensor : SpanService { CarbonDioxideSensor(ServiceType mod=ServiceType::Regular) : SpanService{"97", mod}{} };
struct CarbonDioxideSensor : SpanService { CarbonDioxideSensor() : SpanService{"97"}{} };
struct CarbonMonoxideSensor : SpanService { CarbonMonoxideSensor(ServiceType mod=ServiceType::Regular) : SpanService{"7F", mod}{} };
struct CarbonMonoxideSensor : SpanService { CarbonMonoxideSensor() : SpanService{"7F"}{} };
struct ContactSensor : SpanService { ContactSensor(ServiceType mod=ServiceType::Regular) : SpanService{"80", mod}{} };
struct ContactSensor : SpanService { ContactSensor() : SpanService{"80"}{} };
struct Door : SpanService { Door(ServiceType mod=ServiceType::Regular) : SpanService{"81", mod}{} };
struct Door : SpanService { Door() : SpanService{"81"}{} };
struct Doorbell : SpanService { Doorbell(ServiceType mod=ServiceType::Regular) : SpanService{"121", mod}{} };
struct Doorbell : SpanService { Doorbell() : SpanService{"121"}{} };
struct Fan : SpanService { Fan(ServiceType mod=ServiceType::Regular) : SpanService{"B7", mod}{} };
struct Fan : SpanService { Fan() : SpanService{"B7"}{} };
struct Faucet : SpanService { Faucet(ServiceType mod=ServiceType::Regular) : SpanService{"D7", mod}{} };
struct Faucet : SpanService { Faucet() : SpanService{"D7"}{} };
struct FilterMaintenance : SpanService { FilterMaintenance(ServiceType mod=ServiceType::Regular) : SpanService{"BA", mod}{} };
struct FilterMaintenance : SpanService { FilterMaintenance() : SpanService{"BA"}{} };
struct GarageDoorOpener : SpanService { GarageDoorOpener(ServiceType mod=ServiceType::Regular) : SpanService{"41", mod}{} };
struct GarageDoorOpener : SpanService { GarageDoorOpener() : SpanService{"41"}{} };
struct HAPProtocolInformation : SpanService { HAPProtocolInformation(ServiceType mod=ServiceType::Regular) : SpanService{"A2", mod}{} };
struct HAPProtocolInformation : SpanService { HAPProtocolInformation() : SpanService{"A2"}{} };
struct HeaterCooler : SpanService { HeaterCooler(ServiceType mod=ServiceType::Regular) : SpanService{"BC", mod}{} };
struct HeaterCooler : SpanService { HeaterCooler() : SpanService{"BC"}{} };
struct HumidifierDehumidifier : SpanService { HumidifierDehumidifier(ServiceType mod=ServiceType::Regular) : SpanService{"BD", mod}{} };
struct HumidifierDehumidifier : SpanService { HumidifierDehumidifier() : SpanService{"BD"}{} };
struct HumiditySensor : SpanService { HumiditySensor(ServiceType mod=ServiceType::Regular) : SpanService{"82", mod}{} };
struct HumiditySensor : SpanService { HumiditySensor() : SpanService{"82"}{} };
struct IrrigationSystem : SpanService { IrrigationSystem(ServiceType mod=ServiceType::Regular) : SpanService{"CF", mod}{} };
struct IrrigationSystem : SpanService { IrrigationSystem() : SpanService{"CF"}{} };
struct LeakSensor : SpanService { LeakSensor(ServiceType mod=ServiceType::Regular) : SpanService{"83", mod}{} };
struct LeakSensor : SpanService { LeakSensor() : SpanService{"83"}{} };
struct LightBulb : SpanService { LightBulb(ServiceType mod=ServiceType::Regular) : SpanService{"43", mod}{} };
struct LightBulb : SpanService { LightBulb() : SpanService{"43"}{} };
struct LightSensor : SpanService { LightSensor(ServiceType mod=ServiceType::Regular) : SpanService{"84", mod}{} };
struct LightSensor : SpanService { LightSensor() : SpanService{"84"}{} };
struct MotionSensor : SpanService { MotionSensor(ServiceType mod=ServiceType::Regular) : SpanService{"85", mod}{} };
struct MotionSensor : SpanService { MotionSensor() : SpanService{"85"}{} };
struct OccupancySensor : SpanService { OccupancySensor(ServiceType mod=ServiceType::Regular) : SpanService{"86", mod}{} };
struct OccupancySensor : SpanService { OccupancySensor() : SpanService{"86"}{} };
struct Outlet : SpanService { Outlet(ServiceType mod=ServiceType::Regular) : SpanService{"47", mod}{} };
struct Outlet : SpanService { Outlet() : SpanService{"47"}{} };
struct ServiceLabel : SpanService { ServiceLabel(ServiceType mod=ServiceType::Regular) : SpanService{"47", mod}{} };
struct ServiceLabel : SpanService { ServiceLabel() : SpanService{"47"}{} };
struct Slat : SpanService { Slat(ServiceType mod=ServiceType::Regular) : SpanService{"B9", mod}{} };
struct Slat : SpanService { Slat() : SpanService{"B9"}{} };
struct SmokeSensor : SpanService { SmokeSensor(ServiceType mod=ServiceType::Regular) : SpanService{"87", mod}{} };
struct SmokeSensor : SpanService { SmokeSensor() : SpanService{"87"}{} };
struct StatelessProgrammableSwitch : SpanService { StatelessProgrammableSwitch(ServiceType mod=ServiceType::Regular) : SpanService{"89", mod}{} };
struct StatelessProgrammableSwitch : SpanService { StatelessProgrammableSwitch() : SpanService{"89"}{} };
struct Switch : SpanService { Switch(ServiceType mod=ServiceType::Regular) : SpanService{"49", mod}{} };
struct Switch : SpanService { Switch() : SpanService{"49"}{} };
struct TemperatureSensor : SpanService { TemperatureSensor(ServiceType mod=ServiceType::Regular) : SpanService{"8A", mod}{} };
struct TemperatureSensor : SpanService { TemperatureSensor() : SpanService{"8A"}{} };
struct Thermostat : SpanService { Thermostat(ServiceType mod=ServiceType::Regular) : SpanService{"4A", mod}{} };
struct Thermostat : SpanService { Thermostat() : SpanService{"4A"}{} };
struct Valve : SpanService { Valve(ServiceType mod=ServiceType::Regular) : SpanService{"D0", mod}{} };
struct Valve : SpanService { Valve() : SpanService{"D0"}{} };
struct Window : SpanService { Window(ServiceType mod=ServiceType::Regular) : SpanService{"8B", mod}{} };
struct Window : SpanService { Window() : SpanService{"8B"}{} };
struct WindowCovering : SpanService { WindowCovering(ServiceType mod=ServiceType::Regular) : SpanService{"8C", mod}{} };
struct WindowCovering : SpanService { WindowCovering() : SpanService{"8C"}{} };
}

View File

@ -46,16 +46,6 @@ const int MAX_PWD=64;
#else
#define LOG1(x)
#endif
//////////////////////////////////////////////////////
// Types of Services (default is Regular) //
// Reference: HAP Table 6-2 //
enum ServiceType {
Regular,
Hidden,
Primary
};
//////////////////////////////////////////////////////
// Types of Accessory Categories //