Coding With Fun
Home Docker Django Node.js Articles Python pip guide FAQ Policy

Access to services and features


May 22, 2021 HomeKit App Development guide


Table of contents


Access to services and features

The service (HMService) represents a feature of an accessory and some features with readable writing (HMCharacteristic). A n accessory can have multiple services, a service can also have many features. F or example, a garage door opener may have a lighting and switching service. T he lighting service may have on/off and adjust the brightness characteristics. U sers cannot manufacture smart home appliance accessories and their services - accessories manufacturers make accessories and their services - but users can change the characteristics of the service. S ome features with readable and write properties represent a physical state, for example, the current temperature in a thermostat is a readable value, but the target temperature is readable. Apple has pre-defined the names of some services and features so that Siri can recognize them.

Get the services and attributes of the accessory

After you create an accessory object, as described in Get the Accessroties in a Room, you get the services and features of the accessory. Of course, you can also get different services by type directly from home.

Important: Do not expose anonymous services - such as firmware upgrade services - to users

With the services property of the HMAccessory class object, we can get an accessory service.

NSArray *services = accessroy.services;

To get a specific service from an accessory in home, use the servicesWithTypes: method for HMHome class objects.

// Get all lights and thermostats in a home
NSArray *lightServices = [home servicesWithTypes:[HMServicesTypeLightbulb]];
NSArray *thermostatServices = [home servicesWithTypes:[HMServicesTypeThermostat]];

Use the name property of the HMServices class object to get the name of the service

NSString *name = services.name;

To get the attributes of a service, use the characteristics property.

NSArray *characteristics = service.characteristics

Use the servicesType property to get the type of service

NSString *serviceType = service.serviceType;

Apple defines a number of service types that can be identified by Siri:

  • Door locks
  • Garage door openers
  • Lights
  • Outlets
  • Thermostats

Change the service name

Use updateName:completeHandler: Asynchronous method to change the service name. The service name parameters passed in to this method must be unique in a home, and the service name can be recognized by Siri.

[service updateName:@"Garage 1 Opener" completionHandler:^(NSError *error) {
    if (error) {
        // Failed to change the name
    } else {
        // Successfully changed the name
    }
}];

The value of the access attribute

An attribute represents a parameter of a service that is either read-only, read-writeable, or write-only. I t provides information about possible values for this parameter, such as a boolean or a range value. T he temperature in the thermostat is read-only, and the target temperature is readable. A command that performs a task and does not require any return - such as playing a sound or flashing a light to confirm an accessory - may be written only.

Apple defines the types of features that can be identified by Siri:

  • Brightness
  • Recent temperature
  • Lock State
  • Power State
  • Target State
  • Target temperature

For example, for a garage door opener, the target state is to turn it on or off. For a lock, the target state is locked and unlocked again.

After you get an HMService object, as described by Get Services and Properties, you get the value of the attributes of each service. Because these values are obtained from accessories, these read and write methods are asynchronous and can be passed in to a block that completes the callback.

Use readValueWithCompletionHandler: Asynchronous method to read the value of a feature.

[characteristic readValueWithCompletionHandler:^(NSError *error) {
    if (error == nil) {
       // Successfully read the value
       id value = characteristic.value;
    }
    else {
       // Unable to read the value
} }];

In the if statement block, add your code to update the view of the app.

Use writeValue:contentHandler: Asynchronous method to write a value to an attribute.

[self.characteristic writeValue:@42 withCompletionHandler:^(NSError *error) {
    if (error == nil) {
       // Successfully wrote the value
    }
    else {
       // Unable to write the value
} }];

Don't assume that a function call completes means a successful write, which is actually only indicated when the callback execution is completed without an error being generated. F or example, do not change the state of a switch until its characteristics change. In the if statement block, add your code to update the view of the app.

In addition, the view needs to be updated when other apps update the value of the feature, as described in Observing Changes to Accessories.

Create a service group

An HMService Group provides shortcuts to any number of services that control different accessories - for example, when a user leaves home and controls certain lights in the home.

Access to services and features

After you create an HMHome object, as described in Get the Primary Home and Collection of Homes, you also create a service group in that home.

To create a service group, we use the addService Group WithName:completeHandler: Method for HMHome class objects. The name of the parameter service group in the method must be unique in this home and can be recognized by Siri.

[self.home addServiceGroupWithName:@"Away Lights" completionHandler:^(HMServiceGroup *serviceGroup, NSError *error) {
    if (error == nil) {
       // Successfully created the service group
} else {
       // Unable to create the service group
    }];

We use the addService:completeHandler method for HMService Group class objects: method to add a service to a service group. Services can be in one or more service groups.

[serviceGroup addService:service completionHandler:^(NSError *error) {
    if (error == nil) {
       // Successfully added service to service group
    }
       // Unable to add the service to the service group
    }];

Get all the service groups for this home through the serviceGroups property of the HMHome class object.

NSArray *serviceGroups = self.home.serviceGroups;

Using the accessory property of the HMService Group class object, we get the smart appliances that correspond to the service.

HMAccessory *accessory = service.accessory;

Similar to accessories, proxy methods are called when other apps change service groups. If your app uses a service group, read the HMHomeDelegate Protocol Reference documentation to find out what you should do to observe these changes.