New Services and Characteristics List (#751)

* auto-generation of service list

* Update makeServiceList

* Update makeServiceList

* Update test.md

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* Update Span.h

* Update test.md

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* update

* Create ServiceListHead.md

* Update ServiceListHead.md

* Update ServiceListHead.md

* Update test.md

* update

* update

* Update ServiceList.md

* update

* Update ServiceList.md

* update
This commit is contained in:
HomeSpan 2024-01-23 22:52:54 -05:00 committed by GitHub
parent fe0b8c1a42
commit 3e9e7a1902
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 763 additions and 390 deletions

View File

@ -1,204 +1,448 @@
# HomeSpan Services and Characteristics
HomeSpan implements all HAP-R2 Services and Characteristics except for those that involve video or audio streaming, Apple TV, or advanced lock management (i.e. all HAP Services except those that require Characteristics with a TLV8 data type).
Below is a list of all Services supported by HomeSpan, along with a brief description of each Service. Click on the arrow next to the description of any Service to see a list of all Characteristics supported by the Service, as well as a description of each Characteristic.[^1]
A blue diamond (🔹) next to a Characteristic means it is **required** for that Service, otherwise it is optional. Information included for each Characteristic is as follows:
* **Format** - the native format of the Characteristic's value. Note that *string* means a standard C-string (i.e. char \*)
* **Perms**, where
* PR = Paired Read. This means HomeKit can read the value from HomeSpan[^2]
* PW = Paired Write. This means HomeKit can write the value to HomeSpan, which triggers a call to `update()`
* EV = Event Notification. This means HomeSpan can push notifications of value changes to HomeKit using `setVal()`
* **Min** / **Max** - the default minimum and maximum values allowed in HomeKit. For applicable numerical Characteristics, you can change the allowed minimum and maximum values using `setRange()`
* **Constants/Defaults**
* for enumerated Characteristics, a list of all allowed values in the form of pre-defined constant expressions and their equivalent numeric values. A check mark next to a constant indicates that it is the default value. If your Accessory does not support certain states of a Characteristic, you can change the allowed values using `setValidValues()`
* for all other Characteristics, the actual default value that is used if you do not specify one when instantiating the Characteristic
[^1]: The hexidecimal numbers in parentheses next to each Service and Characteristic represent the short-form of the Apple's UUID for that Service or Characteristic. These are provided for informational purposes only (you do not need to use them, or even know about them, to create HomeSpan sketches)
[^2]: Though rarely needed, you can change the permissions of a Characteristic using `setPerms()`, `addPerms()`, and `removePerms()`
HomeSpan Services and Characteristics are implemented as C++ Classes with names that exactly match the spelling and capitalization specified by Apple in Sections 8 and 9 of HAP-R2, but without any spaces. HomeSpan Services are defined in HomeSpan's `Service` namespace. HomeSpan Characteristics are defined in HomeSpan's `Characteristic` namespace. For example, HomeSpan defines the *Carbon Dioxide Sensor* Service (HAP Service 8.7) as `Service::CarbonDioxideSensor`, and the *Carbon Dioxide Detected* Characteristic (HAP Characteristic 9.16) as `Characteristic::CarbonDioxideDetected`.
HomeSpan Services and Characteristics are instantiated with a C++ `new` command. Services do not take any arguments, whereas Characteristics take a single, optional argument that is used to initialize the value of the Characteristic at startup. If this argument is not specified, HomeSpan will apply a reasonable [default value](#characteristic-types-and-defaults) based on the Characteristic's type and allowed range.
The pre-defined constant expressions for enumerated Characteristics are in namespaces that match the name of the Characteristic. For example, to set the *Air Quality* Characteristic of an *Air Quality Sensor* Service, you could use `setVal(Characteristic::AirQuality::GOOD)` or, equivalently, `setVal(2)`.[^3]
A list of all HomeSpan Services is provided in the table below. For each Service the table also indicates which Characteristics are required and which are optional. For example, a dimmable light bulb could be configured in HomeSpan as such:
[^3]: Note that a Characteristic's pre-defined constants are inherited by objects that you create from that Characteristic. This means that if you create a pointer to the *AirQuality* Characteristic using `Characteristic::AirQuality *air = new Characteristic::AirQuality;` then later in your code you can either say<br> `air->setVal(Characteristic::AirQuality::GOOD)` or `air->GOOD`. Both will work, but the latter is much easier to type.
```C++
new Service::LightBulb(); // instantiate a Light Bulb Service
new Characteristic:On(); // instantiate the required On Characteristic without setting initial value
new Characteristic::Brightness(50); // instantiate an optional Brightness Characteristic and set initial value to 50%
new Characteristic::Name("Living Room Lamp"); // instantiate an optional Name Characteristic for this Service, and set to "Living Room Lamp"
```
# Currently-Supported Services and Characteristics
Please see Sections 8 and 9 of HAP-R2 for a complete description of all HAP Services and Characteristics. Note that HomeSpan's Service and Characteristic Classes already contain all the required HAP fields, such as the UUID, Format, and Permissions, so you don't need to specify any of these parameters.
<!-- AUTOGENERATED_TEXT. DO NOT EDIT THIS LINE OR ANYTHING BELOW -->
Additionally, when first starting up, HomeSpan begins by validating the device's configuration to ensure each Service you instantiate includes all required Characteristics, but does not include any Characteristics that are neither required nor optional. If any errors are found, HomeSpan reports them to the Arduino Serial Monitor.
### Service List
## AccessoryInformation (3E)
<details><summary> Required Identification Information. For each Accessory in a HomeSpan device this <i>must</i> be included as the first Service.</summary><br><table>
<tr><th>Characteristic</th><th>Format</th><th>Perms</th><th>Min</th><th>Max</th><th>Constants/Defaults</th></tr>
<tr><td><b>Identify (14) :small_blue_diamond:</b><ul><li> triggers an update when HomeKit wants HomeSpan to run its identification routine for an Accessory</li></ul></td><td align="center">bool</td><td align="center">PW</td><td align="center">1</td><td align="center">1</td><td><ul><li><b>RUN_ID&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>FirmwareRevision (52) </b><ul><li> must be in form x[.y[.z]] - informational only</li></ul></td><td align="center">string</td><td align="center">PR+EV</td><td align="center">-</td><td align="center">-</td><td align="center">"1.0.0"</td></tr>
<tr><td><b>Manufacturer (20) </b><ul><li> any string - informational only</li></ul></td><td align="center">string</td><td align="center">PR</td><td align="center">-</td><td align="center">-</td><td align="center">"HomeSpan"</td></tr>
<tr><td><b>Model (21) </b><ul><li> any string - informational only</li></ul></td><td align="center">string</td><td align="center">PR</td><td align="center">-</td><td align="center">-</td><td align="center">"HomeSpan-ESP32"</td></tr>
<tr><td><b>Name (23) </b><ul><li> default name of a Service used <i>only</i> during initial pairing</li></ul></td><td align="center">string</td><td align="center">PR</td><td align="center">-</td><td align="center">-</td><td align="center">"unnamed"</td></tr>
<tr><td><b>SerialNumber (30) </b><ul><li> any string - informational only</li></ul></td><td align="center">string</td><td align="center">PR</td><td align="center">-</td><td align="center">-</td><td align="center">"HS-12345"</td></tr>
<tr><td><b>HardwareRevision (53) </b><ul><li> must be in form x[.y[.z]] - informational only</li></ul></td><td align="center">string</td><td align="center">PR</td><td align="center">-</td><td align="center">-</td><td align="center">"1.0.0"</td></tr>
</table></details>
|Service|Required Characteristics|Optional Characteristics|
|-|-|-|
|AccessoryInformation|Identify|FirmwareRevision<br>Manufacturer<br>Model<br>Name<br>SerialNumber<br>HardwareRevision<br>AccessoryFlags|
|AirPurifier|Active<br>CurrentAirPurifierState<br>TargetAirPurifierState|Name<br>RotationSpeed<br>SwingMode<br>LockPhysicalControls|
|AirQualitySensor|AirQuality|Name<br>OzoneDensity<br>NitrogenDioxideDensity<br>SulphurDioxideDensity<br>PM25Density<br>PM10Density<br>VOCDensity<br>StatusActive<br>StatusFault<br>StatusTampered<br>StatusLowBattery|
|BatteryService|BatteryLevel<br>ChargingState<br>StatusLowBattery|Name|
|CarbonDioxideSensor|CarbonDioxideDetected|Name<br>StatusActive<br>StatusFault<br>StatusTampered<br>StatusLowBattery<br>CarbonDioxideLevel<br>CarbonDioxidePeakLevel|
|CarbonMonoxideSensor|CarbonMonoxideDetected|Name<br>StatusActive<br>StatusFault<br>StatusTampered<br>StatusLowBattery<br>CarbonMonoxideLevel<br>CarbonMonoxidePeakLevel|
|ContactSensor|ContactSensorState|Name<br>StatusActive<br>StatusFault<br>StatusTampered<br>StatusLowBattery|
|Door|CurrentPosition<br>TargetPosition<br>PositionState|Name<br>HoldPosition<br>ObstructionDetected|
|Doorbell|ProgrammableSwitchEvent|Name<br>Volume<br>Brightness|
|Fan|Active|Name<br>CurrentFanState<br>TargetFanState<br>RotationDirection<br>RotationSpeed<br>SwingMode<br>LockPhysicalControls|
|Faucet|Active|StatusFault<br>Name|
|FilterMaintenance|FilterChangeIndication|Name<br>FilterLifeLevel<br>ResetFilterIndication|
|GarageDoorOpener|CurrentDoorState<br>TargetDoorState<br>ObstructionDetected|LockCurrentState<br>LockTargetState<br>Name|
|HAPProtocolInformation|Version||HeaterCooler|Active<br>CurrentTemperature<br>CurrentHeaterCoolerState<br>TargetHeaterCoolerState|Name<br>RotationSpeed<br>TemperatureDisplayUnits<br>SwingMode<br>CoolingThresholdTemperature<br>HeatingThresholdTemperature<br>LockPhysicalControls|
|HumidifierDehumidifier|Active<br>CurrentRelativeHumidity<br>CurrentHumidifierDehumidifierState<br>TargetHumidifierDehumidifierState|Name<br>RelativeHumidityDehumidifierThreshold<br>RelativeHumidityHumidifierThreshold<br>RotationSpeed<br>SwingMode<br>WaterLevel<br>LockPhysicalControls|
|HumiditySensor|CurrentRelativeHumidity|Name<br>StatusActive<br>StatusFault<br>StatusTampered<br>StatusLowBattery|
|InputSource|Identifier|ConfiguredName<br>IsConfigured<br>CurrentVisibilityState<br>TargetVisibilityState|
|IrrigationSystem|Active<br>ProgramMode<br>InUse|RemainingDuration<br>StatusFault|
|LeakSensor|LeakDetected|Name<br>StatusActive<br>StatusFault<br>StatusTampered<br>StatusLowBattery|
|LightBulb|On|Brightness<br>Hue<br>Name<br>Saturation<br>ColorTemperature|
|LightSensor|CurrentAmbientLightLevel|Name<br>StatusActive<br>StatusFault<br>StatusTampered<br>StatusLowBattery|
|LockMechanism|LockCurrentState<br>LockTargetState|Name|
|Microphone|Mute|Name<br>Volume|
|MotionSensor|MotionDetected|Name<br>StatusActive<br>StatusFault<br>StatusTampered<br>StatusLowBattery|
|OccupancySensor|OccupancyDetected|Name<br>StatusActive<br>StatusFault<br>StatusTampered<br>StatusLowBattery|
|Outlet|On<br>OutletInUse|Name|
|SecuritySystem|SecuritySystemCurrentState<br>SecuritySystemTargetState|Name<br>SecuritySystemAlarmType<br>StatusFault<br>StatusTampered|
|ServiceLabel|ServiceLabelNamespace||Slat|CurrentSlatState<br>SlatType|Name<br>SwingMode<br>CurrentTiltAngle<br>TargetTiltAngle|
|SmokeSensor|SmokeDetected|Name<br>StatusActive<br>StatusFault<br>StatusTampered<br>StatusLowBattery|
|Speaker|Mute|Name<br>Volume|
|StatelessProgrammableSwitch|ProgrammableSwitchEvent|Name<br>ServiceLabelIndex|
|Switch|On|Name|
|Television|Active|ConfiguredName<br>ActiveIdentifier<br>RemoteKey<br>PowerModeSelection|
|TelevisionSpeaker|VolumeControlType<br>VolumeSelector|
|TemperatureSensor|CurrentTemperature|Name<br>StatusActive<br>StatusFault<br>StatusTampered<br>StatusLowBattery|
|Thermostat|CurrentHeatingCoolingState<br>TargetHeatingCoolingState<br>CurrentTemperature<br>TargetTemperature<br>TemperatureDisplayUnits|CoolingThresholdTemperature<br>CurrentRelativeHumidity<br>HeatingThresholdTemperature<br>Name<br>TargetRelativeHumidity|
|Valve|Active<br>InUse<br>ValveType|SetDuration<br>RemainingDuration<br>IsConfigured<br>ServiceLabelIndex<br>StatusFault<br>Name|
|Window|CurrentPosition<br>TargetPosition<br>PositionState|Name<br>HoldPosition<br>ObstructionDetected|
|WindowCovering|TargetPosition<br>CurrentPosition<br>PositionState|Name<br>HoldPosition<br>CurrentHorizontalTiltAngle<br>TargetHorizontalTiltAngle<br>CurrentVerticalTiltAngle<br>TargetVerticalTiltAngle<br>ObstructionDetected|
## AirPurifier (BB)
<details><summary> Defines a basic Air Purifier with an optional fan. Optional Linked Services: <b>FilterMaintenance</b>, <b>AirQualitySensor</b>, <b>Fan</b>, and <b>Slat</b></summary><br><table>
<tr><th>Characteristic</th><th>Format</th><th>Perms</th><th>Min</th><th>Max</th><th>Constants/Defaults</th></tr>
<tr><td><b>Active (B0) :small_blue_diamond:</b><ul><li> indicates if the Service is active/on</li></ul></td><td align="center">uint8</td><td align="center">PW+PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>INACTIVE&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>ACTIVE&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>CurrentAirPurifierState (A9) :small_blue_diamond:</b><ul><li> indicates current state of air purification</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">2</td><td><ul><li><b>INACTIVE&nbsp(0)&nbsp;</b></li><li><b>IDLE&nbsp(1)&nbsp;</b>:heavy_check_mark:</li><li><b>PURIFYING&nbsp(2)&nbsp;</b></li></ul></td></tr>
<tr><td><b>TargetAirPurifierState (A8) :small_blue_diamond:</b><ul><li> indicates desired state of air purifier</li></ul></td><td align="center">uint8</td><td align="center">PW+PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>MANUAL&nbsp(0)&nbsp;</b></li><li><b>AUTO&nbsp(1)&nbsp;</b>:heavy_check_mark:</li></ul></td></tr>
<tr><td><b>Name (23) </b><ul><li> default name of a Service used <i>only</i> during initial pairing</li></ul></td><td align="center">string</td><td align="center">PR</td><td align="center">-</td><td align="center">-</td><td align="center">"unnamed"</td></tr>
<tr><td><b>RotationSpeed (29) </b><ul><li> measured as a percentage</li></ul></td><td align="center">float</td><td align="center">PR+PW+EV</td><td align="center">0</td><td align="center">100</td><td align="center">0</td></tr>
<tr><td><b>SwingMode (B6) </b><ul><li> indicates whether swing-nmode is enabled</li></ul></td><td align="center">uint8</td><td align="center">PR+EV+PW</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>SWING_DISABLED&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>SWING_ENABLED&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>LockPhysicalControls (A7) </b><ul><li> indicates if local control lock is enabled</li></ul></td><td align="center">uint8</td><td align="center">PW+PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>CONTROL_LOCK_DISABLED&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>CONTROL_LOCK_ENABLED&nbsp(1)&nbsp;</b></li></ul></td></tr>
</table></details>
### Characteristic Types and Defaults
## AirQualitySensor (8D)
<details><summary> Defines an Air Quality Sensor. </summary><br><table>
<tr><th>Characteristic</th><th>Format</th><th>Perms</th><th>Min</th><th>Max</th><th>Constants/Defaults</th></tr>
<tr><td><b>AirQuality (95) :small_blue_diamond:</b><ul><li> a subjective description</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">5</td><td><ul><li><b>UNKNOWN&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>EXCELLENT&nbsp(1)&nbsp;</b></li><li><b>GOOD&nbsp(2)&nbsp;</b></li><li><b>FAIR&nbsp(3)&nbsp;</b></li><li><b>INFERIOR&nbsp(4)&nbsp;</b></li><li><b>POOR&nbsp(5)&nbsp;</b></li></ul></td></tr>
<tr><td><b>Name (23) </b><ul><li> default name of a Service used <i>only</i> during initial pairing</li></ul></td><td align="center">string</td><td align="center">PR</td><td align="center">-</td><td align="center">-</td><td align="center">"unnamed"</td></tr>
<tr><td><b>OzoneDensity (C3) </b><ul><li> measured in &micro;g/m<sup>3</sup></li></ul></td><td align="center">float</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1000</td><td align="center">0</td></tr>
<tr><td><b>NitrogenDioxideDensity (C4) </b><ul><li> measured in &micro;g/m<sup>3</sup></li></ul></td><td align="center">float</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1000</td><td align="center">0</td></tr>
<tr><td><b>SulphurDioxideDensity (C5) </b><ul><li> measured in &micro;g/m<sup>3</sup></li></ul></td><td align="center">float</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1000</td><td align="center">0</td></tr>
<tr><td><b>PM25Density (C6) </b><ul><li> 2.5-micron particulate density, measured in &micro;g/m<sup>3</sup></li></ul></td><td align="center">float</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1000</td><td align="center">0</td></tr>
<tr><td><b>PM10Density (C7) </b><ul><li> 10-micron particulate density, measured in &micro;g/m<sup>3</sup></li></ul></td><td align="center">float</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1000</td><td align="center">0</td></tr>
<tr><td><b>VOCDensity (C8) </b><ul><li> measured in &micro;g/m<sup>3</sup></li></ul></td><td align="center">float</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1000</td><td align="center">0</td></tr>
<tr><td><b>StatusActive (75) </b><ul><li> indicates whether the Service is properly functioning </li></ul></td><td align="center">bool</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_FUNCTIONING&nbsp(0)&nbsp;</b></li><li><b>FUNCTIONING&nbsp(1)&nbsp;</b>:heavy_check_mark:</li></ul></td></tr>
<tr><td><b>StatusFault (77) </b><ul><li> indicates whether the Service has a fault</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NO_FAULT&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>FAULT&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>StatusTampered (7A) </b><ul><li> indicates whether the Service has been tampered with</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_TAMPERED&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>TAMPERED&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>StatusLowBattery (79) </b><ul><li> indicates state of battery</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_LOW_BATTERY&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>LOW_BATTERY&nbsp(1)&nbsp;</b></li></ul></td></tr>
</table></details>
|Characteristic|Type|Default|Range|
|-|-|-|-|
AccessoryFlags|uint32_t|1|[1,1]|
Active|uint8_t|0|[0,1]|
ActiveIdentifier|uint32_t|0|[0,255]|
AirQuality|uint8_t|0|[0,5]|
BatteryLevel|uint8_t|0|[0,100]|
Brightness|int|0|[0,100]|
CarbonMonoxideLevel|double|0|[0,100]|
CarbonMonoxidePeakLevel|double|0|[0,100]|
CarbonMonoxideDetected|uint8_t|0|[0,1]|
CarbonDioxideLevel|double|0|[0,100000]|
CarbonDioxidePeakLevel|double|0|[0,100000]|
CarbonDioxideDetected|uint8_t|0|[0,1]|
ChargingState|uint8_t|0|[0,2]|
ClosedCaptions|uint8_t|0|[0,1]|
CoolingThresholdTemperature|double|10|[10,35]|
ColorTemperature|uint32_t|200|[140,500]|
ContactSensorState|uint8_t|1|[0,1]|
ConfiguredName|char \*|"unnamed"|||
CurrentAmbientLightLevel|double|1|[0.0001,100000]|
CurrentHorizontalTiltAngle|int|0|[-90,90]|
CurrentAirPurifierState|uint8_t|1|[0,2]|
CurrentSlatState|uint8_t|0|[0,2]|
CurrentPosition|uint8_t|0|[0,100]|
CurrentVerticalTiltAngle|int|0|[-90,90]|
CurrentVisibilityState|uint8_t|0|[0,1]|
CurrentHumidifierDehumidifierState|uint8_t|1|[0,3]|
CurrentDoorState|uint8_t|1|[0,4]|
CurrentFanState|uint8_t|1|[0,2]|
CurrentHeatingCoolingState|uint8_t|0|[0,2]|
CurrentHeaterCoolerState|uint8_t|1|[0,3]|
CurrentMediaState|uint8_t|0|[0,5]|
CurrentRelativeHumidity|double|0|[0,100]|
CurrentTemperature|double|0|[0,100]|
CurrentTiltAngle|int|0|[-90,90]|
FilterLifeLevel|double|0|[0,100]|
FilterChangeIndication|uint8_t|0|[0,1]|
FirmwareRevision|char \*|"1.0.0"|||
HardwareRevision|char \*|"1.0.0"|||
HeatingThresholdTemperature|double|16|[0,25]|
HoldPosition|boolean|false|[0,1]|
Hue|double|0|[0,360]|
Identify|boolean|false|[0,1]|
Identifier|uint32_t|0|[0,255]|
InputDeviceType|uint8_t|0|[0,6]|
InputSourceType|uint8_t|0|[0,10]|
InUse|uint8_t|0|[0,1]|
IsConfigured|uint8_t|0|[0,1]|
LeakDetected|uint8_t|0|[0,1]|
LockCurrentState|uint8_t|0|[0,3]|
LockPhysicalControls|uint8_t|0|[0,1]|
LockTargetState|uint8_t|0|[0,1]|
Manufacturer|char \*|"HomeSpan"|||
Model|char \*|"HomeSpan-ESP32"|||
MotionDetected|boolean|false|[0,1]|
Mute|boolean|false|[0,1]|
Name|char \*|"unnamed"|||
NitrogenDioxideDensity|double|0|[0,1000]|
ObstructionDetected|boolean|false|[0,1]|
PM25Density|double|0|[0,1000]|
OccupancyDetected|uint8_t|0|[0,1]|
OutletInUse|boolean|false|[0,1]|
On|boolean|false|[0,1]|
OzoneDensity|double|0|[0,1000]|
PictureMode|uint8_t|0|[0,13]|
PM10Density|double|0|[0,1000]|
PositionState|uint8_t|2|[0,2]|
PowerModeSelection|uint8_t|0|[0,1]|
ProgramMode|uint8_t|0|[0,2]|
ProgrammableSwitchEvent|uint8_t|0|[0,2]|
RelativeHumidityDehumidifierThreshold|double|50|[0,100]|
RelativeHumidityHumidifierThreshold|double|50|[0,100]|
RemainingDuration|uint32_t|60|[0,3600]|
RemoteKey|uint8_t|0|[0,16]|
ResetFilterIndication|uint8_t|0|[1,1]|
RotationDirection|int|0|[0,1]|
RotationSpeed|double|0|[0,100]|
Saturation|double|0|[0,100]|
SecuritySystemAlarmType|uint8_t|0|[0,1]|
SecuritySystemCurrentState|uint8_t|3|[0,4]|
SecuritySystemTargetState|uint8_t|3|[0,3]|
SerialNumber|char \*|"HS-12345"|||
ServiceLabelIndex|uint8_t|1|[1,255]|
ServiceLabelNamespace|uint8_t|1|[0,1]|
SlatType|uint8_t|0|[0,1]|
SleepDiscoveryMode|uint8_t|0|[0,1]|
SmokeDetected|uint8_t|0|[0,1]|
StatusActive|boolean|true|[0,1]|
StatusFault|uint8_t|0|[0,1]|
StatusJammed|uint8_t|0|[0,1]|
StatusLowBattery|uint8_t|0|[0,1]|
StatusTampered|uint8_t|0|[0,1]|
SulphurDioxideDensity|double|0|[0,1000]|
SwingMode|uint8_t|0|[0,1]|
TargetAirPurifierState|uint8_t|1|[0,1]|
TargetFanState|uint8_t|1|[0,1]|
TargetTiltAngle|int|0|[-90,90]|
TargetHeaterCoolerState|uint8_t|0|[0,2]|
SetDuration|uint32_t|60|[0,3600]|
TargetHorizontalTiltAngle|int|0|[-90,90]|
TargetHumidifierDehumidifierState|uint8_t|0|[0,2]|
TargetPosition|uint8_t|0|[0,100]|
TargetDoorState|uint8_t|1|[0,1]|
TargetHeatingCoolingState|uint8_t|0|[0,3]|
TargetMediaState|uint8_t|0|[0,2]|
TargetRelativeHumidity|double|0|[0,100]|
TargetTemperature|double|16|[10,38]|
TargetVisibilityState|uint8_t|0|[0,1]|
TemperatureDisplayUnits|uint8_t|0|[0,1]|
TargetVerticalTiltAngle|int|0|[-90,90]|
ValveType|uint8_t|0|[0,3]|
Version|char \*|"1.0.0"|||
VOCDensity|double|0|[0,1000]|
Volume|uint8_t|0|[0,100]|
VolumeControlType|uint8_t|0|[0,3]|
VolumeSelector|uint8_t|0|[0,1]|
WaterLevel|double|0|[0,100]|
## BatteryService (96)
<details><summary> Defines a standalone Battery Service.</summary><br><table>
<tr><th>Characteristic</th><th>Format</th><th>Perms</th><th>Min</th><th>Max</th><th>Constants/Defaults</th></tr>
<tr><td><b>BatteryLevel (68) :small_blue_diamond:</b><ul><li> measured as a percentage</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">100</td><td align="center">100</td></tr>
<tr><td><b>ChargingState (8F) :small_blue_diamond:</b><ul><li> indicates state of battery charging</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">2</td><td><ul><li><b>NOT_CHARGING&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>CHARGING&nbsp(1)&nbsp;</b></li><li><b>NOT_CHARGEABLE&nbsp(2)&nbsp;</b></li></ul></td></tr>
<tr><td><b>StatusLowBattery (79) :small_blue_diamond:</b><ul><li> indicates state of battery</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_LOW_BATTERY&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>LOW_BATTERY&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>Name (23) </b><ul><li> default name of a Service used <i>only</i> during initial pairing</li></ul></td><td align="center">string</td><td align="center">PR</td><td align="center">-</td><td align="center">-</td><td align="center">"unnamed"</td></tr>
</table></details>
### HAP Format Codes (HAP-R2 Table 6-5)
## CarbonDioxideSensor (97)
<details><summary> Defines a Carbon Dioxide Sensor.</summary><br><table>
<tr><th>Characteristic</th><th>Format</th><th>Perms</th><th>Min</th><th>Max</th><th>Constants/Defaults</th></tr>
<tr><td><b>CarbonDioxideDetected (92) :small_blue_diamond:</b><ul><li> indicates if abnormal level is detected</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NORMAL&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>ABNORMAL&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>Name (23) </b><ul><li> default name of a Service used <i>only</i> during initial pairing</li></ul></td><td align="center">string</td><td align="center">PR</td><td align="center">-</td><td align="center">-</td><td align="center">"unnamed"</td></tr>
<tr><td><b>StatusActive (75) </b><ul><li> indicates whether the Service is properly functioning </li></ul></td><td align="center">bool</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_FUNCTIONING&nbsp(0)&nbsp;</b></li><li><b>FUNCTIONING&nbsp(1)&nbsp;</b>:heavy_check_mark:</li></ul></td></tr>
<tr><td><b>StatusFault (77) </b><ul><li> indicates whether the Service has a fault</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NO_FAULT&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>FAULT&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>StatusTampered (7A) </b><ul><li> indicates whether the Service has been tampered with</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_TAMPERED&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>TAMPERED&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>StatusLowBattery (79) </b><ul><li> indicates state of battery</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_LOW_BATTERY&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>LOW_BATTERY&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>CarbonDioxideLevel (93) </b><ul><li> measured on parts per million (ppm)</li></ul></td><td align="center">float</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">100000</td><td align="center">0</td></tr>
<tr><td><b>CarbonDioxidePeakLevel (94) </b><ul><li> measured in parts per million (ppm)</li></ul></td><td align="center">float</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">100000</td><td align="center">0</td></tr>
</table></details>
|HAP-R2 Format Code|HomeSpan C++ Type|
|------------------|-----------------|
|BOOL|boolean|
|UINT8|uint8_t|
|UINT16|uint16_t|
|UINT32|uint32_t|
|UINT64|uint64_t|
|INT|int|
|FLOAT|double|
|STRING|char \*|
|TLV8|(not implemented)|
|DATA|uint8_t *|
## CarbonMonoxideSensor (7F)
<details><summary> Defines a Carbon Monoxide Sensor.</summary><br><table>
<tr><th>Characteristic</th><th>Format</th><th>Perms</th><th>Min</th><th>Max</th><th>Constants/Defaults</th></tr>
<tr><td><b>CarbonMonoxideDetected (69) :small_blue_diamond:</b><ul><li> indicates if abnormal level is detected</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NORMAL&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>ABNORMAL&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>Name (23) </b><ul><li> default name of a Service used <i>only</i> during initial pairing</li></ul></td><td align="center">string</td><td align="center">PR</td><td align="center">-</td><td align="center">-</td><td align="center">"unnamed"</td></tr>
<tr><td><b>StatusActive (75) </b><ul><li> indicates whether the Service is properly functioning </li></ul></td><td align="center">bool</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_FUNCTIONING&nbsp(0)&nbsp;</b></li><li><b>FUNCTIONING&nbsp(1)&nbsp;</b>:heavy_check_mark:</li></ul></td></tr>
<tr><td><b>StatusFault (77) </b><ul><li> indicates whether the Service has a fault</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NO_FAULT&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>FAULT&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>StatusTampered (7A) </b><ul><li> indicates whether the Service has been tampered with</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_TAMPERED&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>TAMPERED&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>StatusLowBattery (79) </b><ul><li> indicates state of battery</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_LOW_BATTERY&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>LOW_BATTERY&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>CarbonMonoxideLevel (90) </b><ul><li> measured in parts per million (ppm)</li></ul></td><td align="center">float</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">100</td><td align="center">0</td></tr>
<tr><td><b>CarbonMonoxidePeakLevel (91) </b><ul><li> measured in parts per million (ppm)</li></ul></td><td align="center">float</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">100</td><td align="center">0</td></tr>
</table></details>
## ContactSensor (80)
<details><summary> Defines a Contact Sensor.</summary><br><table>
<tr><th>Characteristic</th><th>Format</th><th>Perms</th><th>Min</th><th>Max</th><th>Constants/Defaults</th></tr>
<tr><td><b>ContactSensorState (6A) :small_blue_diamond:</b><ul><li> indictates if contact is detected (i.e. closed)</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>DETECTED&nbsp(0)&nbsp;</b></li><li><b>NOT_DETECTED&nbsp(1)&nbsp;</b>:heavy_check_mark:</li></ul></td></tr>
<tr><td><b>Name (23) </b><ul><li> default name of a Service used <i>only</i> during initial pairing</li></ul></td><td align="center">string</td><td align="center">PR</td><td align="center">-</td><td align="center">-</td><td align="center">"unnamed"</td></tr>
<tr><td><b>StatusActive (75) </b><ul><li> indicates whether the Service is properly functioning </li></ul></td><td align="center">bool</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_FUNCTIONING&nbsp(0)&nbsp;</b></li><li><b>FUNCTIONING&nbsp(1)&nbsp;</b>:heavy_check_mark:</li></ul></td></tr>
<tr><td><b>StatusFault (77) </b><ul><li> indicates whether the Service has a fault</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NO_FAULT&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>FAULT&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>StatusTampered (7A) </b><ul><li> indicates whether the Service has been tampered with</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_TAMPERED&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>TAMPERED&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>StatusLowBattery (79) </b><ul><li> indicates state of battery</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_LOW_BATTERY&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>LOW_BATTERY&nbsp(1)&nbsp;</b></li></ul></td></tr>
</table></details>
## Door (81)
<details><summary> Defines a motorized Door.</summary><br><table>
<tr><th>Characteristic</th><th>Format</th><th>Perms</th><th>Min</th><th>Max</th><th>Constants/Defaults</th></tr>
<tr><td><b>CurrentPosition (6D) :small_blue_diamond:</b><ul><li> current position (as a percentage) from fully closed (0) to full open (100)</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">100</td><td align="center">0</td></tr>
<tr><td><b>TargetPosition (7C) :small_blue_diamond:</b><ul><li> indicates target position (as a percentage) from fully closed (0) to full open (100)</li></ul></td><td align="center">uint8</td><td align="center">PW+PR+EV</td><td align="center">0</td><td align="center">100</td><td align="center">0</td></tr>
<tr><td><b>Name (23) </b><ul><li> default name of a Service used <i>only</i> during initial pairing</li></ul></td><td align="center">string</td><td align="center">PR</td><td align="center">-</td><td align="center">-</td><td align="center">"unnamed"</td></tr>
<tr><td><b>ObstructionDetected (24) </b><ul><li> indicates if obstruction is detected</li></ul></td><td align="center">bool</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_DETECTED&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>DETECTED&nbsp(1)&nbsp;</b></li></ul></td></tr>
</table></details>
## Doorbell (121)
<details><summary> Defines a Doorbell. Can be used on a standalone basis or in conjunction with a <b>LockMechanism</b> Service.</summary><br><table>
<tr><th>Characteristic</th><th>Format</th><th>Perms</th><th>Min</th><th>Max</th><th>Constants/Defaults</th></tr>
<tr><td><b>ProgrammableSwitchEvent (73) :small_blue_diamond:</b><ul><li> specifies type of button press</li></ul></td><td align="center">uint8</td><td align="center">PR+EV+NV</td><td align="center">0</td><td align="center">2</td><td><ul><li><b>SINGLE_PRESS&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>DOUBLE_PRESS&nbsp(1)&nbsp;</b></li><li><b>LONG_PRESS&nbsp(2)&nbsp;</b></li></ul></td></tr>
<tr><td><b>Name (23) </b><ul><li> default name of a Service used <i>only</i> during initial pairing</li></ul></td><td align="center">string</td><td align="center">PR</td><td align="center">-</td><td align="center">-</td><td align="center">"unnamed"</td></tr>
</table></details>
## Fan (B7)
<details><summary> Defines a Fan. Can be used in conjunction with a <b>LightBulb</b> Service to create a Lighted Ceiling Fan.</summary><br><table>
<tr><th>Characteristic</th><th>Format</th><th>Perms</th><th>Min</th><th>Max</th><th>Constants/Defaults</th></tr>
<tr><td><b>Active (B0) :small_blue_diamond:</b><ul><li> indicates if the Service is active/on</li></ul></td><td align="center">uint8</td><td align="center">PW+PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>INACTIVE&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>ACTIVE&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>Name (23) </b><ul><li> default name of a Service used <i>only</i> during initial pairing</li></ul></td><td align="center">string</td><td align="center">PR</td><td align="center">-</td><td align="center">-</td><td align="center">"unnamed"</td></tr>
<tr><td><b>CurrentFanState (AF) </b><ul><li> indicates current state of a fan</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">2</td><td><ul><li><b>INACTIVE&nbsp(0)&nbsp;</b></li><li><b>IDLE&nbsp(1)&nbsp;</b>:heavy_check_mark:</li><li><b>BLOWING&nbsp(2)&nbsp;</b></li></ul></td></tr>
<tr><td><b>TargetFanState (BF) </b><ul><li> indicates desired state of fan</li></ul></td><td align="center">uint8</td><td align="center">PW+PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>MANUAL&nbsp(0)&nbsp;</b></li><li><b>AUTO&nbsp(1)&nbsp;</b>:heavy_check_mark:</li></ul></td></tr>
<tr><td><b>RotationDirection (28) </b><ul><li> indicates the rotation direction of a fan</li></ul></td><td align="center">int</td><td align="center">PR+PW+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>CLOCKWISE&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>COUNTERCLOCKWISE&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>RotationSpeed (29) </b><ul><li> measured as a percentage</li></ul></td><td align="center">float</td><td align="center">PR+PW+EV</td><td align="center">0</td><td align="center">100</td><td align="center">0</td></tr>
<tr><td><b>SwingMode (B6) </b><ul><li> indicates whether swing-nmode is enabled</li></ul></td><td align="center">uint8</td><td align="center">PR+EV+PW</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>SWING_DISABLED&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>SWING_ENABLED&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>LockPhysicalControls (A7) </b><ul><li> indicates if local control lock is enabled</li></ul></td><td align="center">uint8</td><td align="center">PW+PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>CONTROL_LOCK_DISABLED&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>CONTROL_LOCK_ENABLED&nbsp(1)&nbsp;</b></li></ul></td></tr>
</table></details>
## Faucet (D7)
<details><summary> Defines the master control for a multi-Valve appliance. Linked Services: <b>Valve</b> (at least one <i>required</i>), and <b>HeaterCooler</b> (optional).</summary><br><table>
<tr><th>Characteristic</th><th>Format</th><th>Perms</th><th>Min</th><th>Max</th><th>Constants/Defaults</th></tr>
<tr><td><b>Active (B0) :small_blue_diamond:</b><ul><li> indicates if the Service is active/on</li></ul></td><td align="center">uint8</td><td align="center">PW+PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>INACTIVE&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>ACTIVE&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>StatusFault (77) </b><ul><li> indicates whether the Service has a fault</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NO_FAULT&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>FAULT&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>Name (23) </b><ul><li> default name of a Service used <i>only</i> during initial pairing</li></ul></td><td align="center">string</td><td align="center">PR</td><td align="center">-</td><td align="center">-</td><td align="center">"unnamed"</td></tr>
</table></details>
## FilterMaintenance (BA)
<details><summary> Defines a Filter Maintainence check.</summary><br><table>
<tr><th>Characteristic</th><th>Format</th><th>Perms</th><th>Min</th><th>Max</th><th>Constants/Defaults</th></tr>
<tr><td><b>FilterChangeIndication (AC) :small_blue_diamond:</b><ul><li> indicates state of filter</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NO_CHANGE_NEEDED&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>CHANGE_NEEDED&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>Name (23) </b><ul><li> default name of a Service used <i>only</i> during initial pairing</li></ul></td><td align="center">string</td><td align="center">PR</td><td align="center">-</td><td align="center">-</td><td align="center">"unnamed"</td></tr>
<tr><td><b>FilterLifeLevel (AB) </b><ul><li> measures as a percentage of remaining life</li></ul></td><td align="center">float</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">100</td><td align="center">0</td></tr>
<tr><td><b>ResetFilterIndication (AD) </b><ul><li> triggers and update when the user chooses to reset the <b>FilterChangeIndication</b> from the Home App</li></ul></td><td align="center">uint8</td><td align="center">PW</td><td align="center">1</td><td align="center">1</td><td><ul><li><b>RESET_FILTER&nbsp(1)&nbsp;</b></li></ul></td></tr>
</table></details>
## GarageDoorOpener (41)
<details><summary> Defines a motorized Garage Door Opener.</summary><br><table>
<tr><th>Characteristic</th><th>Format</th><th>Perms</th><th>Min</th><th>Max</th><th>Constants/Defaults</th></tr>
<tr><td><b>CurrentDoorState (E) :small_blue_diamond:</b><ul><li> indicates current state of a door</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">4</td><td><ul><li><b>OPEN&nbsp(0)&nbsp;</b></li><li><b>CLOSED&nbsp(1)&nbsp;</b>:heavy_check_mark:</li><li><b>OPENING&nbsp(2)&nbsp;</b></li><li><b>CLOSING&nbsp(3)&nbsp;</b></li><li><b>STOPPED&nbsp(4)&nbsp;</b></li></ul></td></tr>
<tr><td><b>TargetDoorState (32) :small_blue_diamond:</b><ul><li> indicates desired state of door</li></ul></td><td align="center">uint8</td><td align="center">PW+PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>OPEN&nbsp(0)&nbsp;</b></li><li><b>CLOSED&nbsp(1)&nbsp;</b>:heavy_check_mark:</li></ul></td></tr>
<tr><td><b>ObstructionDetected (24) :small_blue_diamond:</b><ul><li> indicates if obstruction is detected</li></ul></td><td align="center">bool</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_DETECTED&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>DETECTED&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>LockCurrentState (1D) </b><ul><li> indicates state of a lock</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">3</td><td><ul><li><b>UNLOCKED&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>LOCKED&nbsp(1)&nbsp;</b></li><li><b>JAMMED&nbsp(2)&nbsp;</b></li><li><b>UNKNOWN&nbsp(3)&nbsp;</b></li></ul></td></tr>
<tr><td><b>LockTargetState (1E) </b><ul><li> indicates desired state of lock</li></ul></td><td align="center">uint8</td><td align="center">PW+PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>UNLOCK&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>LOCK&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>Name (23) </b><ul><li> default name of a Service used <i>only</i> during initial pairing</li></ul></td><td align="center">string</td><td align="center">PR</td><td align="center">-</td><td align="center">-</td><td align="center">"unnamed"</td></tr>
<tr><td><b>Version (37) :small_blue_diamond:</b><ul><li> unused</li></ul></td><td align="center">string</td><td align="center">PR</td><td align="center">-</td><td align="center">-</td><td align="center">"1.0.0"</td></tr>
</table></details>
## HeaterCooler (BC)
<details><summary> Defines a standalone Heater, Cooler, or combined Heater/Cooler. Can be used with a separate <b>Fan</b> Service and/or <b>Slat</b> Service to extend functionality.</summary><br><table>
<tr><th>Characteristic</th><th>Format</th><th>Perms</th><th>Min</th><th>Max</th><th>Constants/Defaults</th></tr>
<tr><td><b>Active (B0) :small_blue_diamond:</b><ul><li> indicates if the Service is active/on</li></ul></td><td align="center">uint8</td><td align="center">PW+PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>INACTIVE&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>ACTIVE&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>CurrentTemperature (11) :small_blue_diamond:</b><ul><li> current temperature measured in Celsius</li></ul></td><td align="center">float</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">100</td><td align="center">0</td></tr>
<tr><td><b>CurrentHeaterCoolerState (B1) :small_blue_diamond:</b><ul><li> indicates whether appliance is currently heating, cooling, idle, or off</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">3</td><td><ul><li><b>INACTIVE&nbsp(0)&nbsp;</b></li><li><b>IDLE&nbsp(1)&nbsp;</b>:heavy_check_mark:</li><li><b>HEATING&nbsp(2)&nbsp;</b></li><li><b>COOLING&nbsp(3)&nbsp;</b></li></ul></td></tr>
<tr><td><b>TargetHeaterCoolerState (B2) :small_blue_diamond:</b><ul><li> indicates desired state of heater/cooler</li></ul></td><td align="center">uint8</td><td align="center">PW+PR+EV</td><td align="center">0</td><td align="center">2</td><td><ul><li><b>AUTO&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>HEAT&nbsp(1)&nbsp;</b></li><li><b>COOL&nbsp(2)&nbsp;</b></li></ul></td></tr>
<tr><td><b>Name (23) </b><ul><li> default name of a Service used <i>only</i> during initial pairing</li></ul></td><td align="center">string</td><td align="center">PR</td><td align="center">-</td><td align="center">-</td><td align="center">"unnamed"</td></tr>
<tr><td><b>RotationSpeed (29) </b><ul><li> measured as a percentage</li></ul></td><td align="center">float</td><td align="center">PR+PW+EV</td><td align="center">0</td><td align="center">100</td><td align="center">0</td></tr>
<tr><td><b>TemperatureDisplayUnits (36) </b><ul><li> indicates the desired units to display the temperature on the device itself (has no effect on Home App)</li></ul></td><td align="center">uint8</td><td align="center">PW+PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>CELSIUS&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>FAHRENHEIT&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>SwingMode (B6) </b><ul><li> indicates whether swing-nmode is enabled</li></ul></td><td align="center">uint8</td><td align="center">PR+EV+PW</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>SWING_DISABLED&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>SWING_ENABLED&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>CoolingThresholdTemperature (D) </b><ul><li> cooling turns on when temperature (in Celsius) rises above this threshold</li></ul></td><td align="center">float</td><td align="center">PR+PW+EV</td><td align="center">10</td><td align="center">35</td><td align="center">10</td></tr>
<tr><td><b>HeatingThresholdTemperature (12) </b><ul><li> heating turns on when temperature (in Celsius) falls below this threshold</li></ul></td><td align="center">float</td><td align="center">PR+PW+EV</td><td align="center">0</td><td align="center">25</td><td align="center">16</td></tr>
<tr><td><b>LockPhysicalControls (A7) </b><ul><li> indicates if local control lock is enabled</li></ul></td><td align="center">uint8</td><td align="center">PW+PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>CONTROL_LOCK_DISABLED&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>CONTROL_LOCK_ENABLED&nbsp(1)&nbsp;</b></li></ul></td></tr>
</table></details>
## HumidifierDehumidifier (BD)
<details><summary> Defines a Humidifer, Dehumidifier, or combined Humidifer/Dehumidifier. Can be used with a separate <b>Fan</b> Service and/or <b>Slat</b> Service to extend functionality.</summary><br><table>
<tr><th>Characteristic</th><th>Format</th><th>Perms</th><th>Min</th><th>Max</th><th>Constants/Defaults</th></tr>
<tr><td><b>Active (B0) :small_blue_diamond:</b><ul><li> indicates if the Service is active/on</li></ul></td><td align="center">uint8</td><td align="center">PW+PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>INACTIVE&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>ACTIVE&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>CurrentRelativeHumidity (10) :small_blue_diamond:</b><ul><li> current humidity measured as a percentage</li></ul></td><td align="center">float</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">100</td><td align="center">0</td></tr>
<tr><td><b>CurrentHumidifierDehumidifierState (B3) :small_blue_diamond:</b><ul><li> indicates current state of humidifier/dehumidifer</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">3</td><td><ul><li><b>INACTIVE&nbsp(0)&nbsp;</b></li><li><b>IDLE&nbsp(1)&nbsp;</b>:heavy_check_mark:</li><li><b>HUMIDIFYING&nbsp(2)&nbsp;</b></li><li><b>DEHUMIDIFYING&nbsp(3)&nbsp;</b></li></ul></td></tr>
<tr><td><b>TargetHumidifierDehumidifierState (B4) :small_blue_diamond:</b><ul><li> indicates desired state of humidifier/dehumidifier</li></ul></td><td align="center">uint8</td><td align="center">PW+PR+EV</td><td align="center">0</td><td align="center">2</td><td><ul><li><b>AUTO&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>HUMIDIFY&nbsp(1)&nbsp;</b></li><li><b>DEHUMIDIFY&nbsp(2)&nbsp;</b></li></ul></td></tr>
<tr><td><b>Name (23) </b><ul><li> default name of a Service used <i>only</i> during initial pairing</li></ul></td><td align="center">string</td><td align="center">PR</td><td align="center">-</td><td align="center">-</td><td align="center">"unnamed"</td></tr>
<tr><td><b>RelativeHumidityDehumidifierThreshold (C9) </b><ul><li> dehumidfier turns on when humidity rises above this threshold</li></ul></td><td align="center">float</td><td align="center">PR+PW+EV</td><td align="center">0</td><td align="center">100</td><td align="center">50</td></tr>
<tr><td><b>RelativeHumidityHumidifierThreshold (CA) </b><ul><li> humidfier turns on when humidity falls below this threshold</li></ul></td><td align="center">float</td><td align="center">PR+PW+EV</td><td align="center">0</td><td align="center">100</td><td align="center">50</td></tr>
<tr><td><b>RotationSpeed (29) </b><ul><li> measured as a percentage</li></ul></td><td align="center">float</td><td align="center">PR+PW+EV</td><td align="center">0</td><td align="center">100</td><td align="center">0</td></tr>
<tr><td><b>SwingMode (B6) </b><ul><li> indicates whether swing-nmode is enabled</li></ul></td><td align="center">uint8</td><td align="center">PR+EV+PW</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>SWING_DISABLED&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>SWING_ENABLED&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>WaterLevel (B5) </b><ul><li> measured as a percentage</li></ul></td><td align="center">float</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">100</td><td align="center">0</td></tr>
<tr><td><b>LockPhysicalControls (A7) </b><ul><li> indicates if local control lock is enabled</li></ul></td><td align="center">uint8</td><td align="center">PW+PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>CONTROL_LOCK_DISABLED&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>CONTROL_LOCK_ENABLED&nbsp(1)&nbsp;</b></li></ul></td></tr>
</table></details>
## HumiditySensor (82)
<details><summary> Defines a Humidity Sensor.</summary><br><table>
<tr><th>Characteristic</th><th>Format</th><th>Perms</th><th>Min</th><th>Max</th><th>Constants/Defaults</th></tr>
<tr><td><b>CurrentRelativeHumidity (10) :small_blue_diamond:</b><ul><li> current humidity measured as a percentage</li></ul></td><td align="center">float</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">100</td><td align="center">0</td></tr>
<tr><td><b>Name (23) </b><ul><li> default name of a Service used <i>only</i> during initial pairing</li></ul></td><td align="center">string</td><td align="center">PR</td><td align="center">-</td><td align="center">-</td><td align="center">"unnamed"</td></tr>
<tr><td><b>StatusActive (75) </b><ul><li> indicates whether the Service is properly functioning </li></ul></td><td align="center">bool</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_FUNCTIONING&nbsp(0)&nbsp;</b></li><li><b>FUNCTIONING&nbsp(1)&nbsp;</b>:heavy_check_mark:</li></ul></td></tr>
<tr><td><b>StatusFault (77) </b><ul><li> indicates whether the Service has a fault</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NO_FAULT&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>FAULT&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>StatusTampered (7A) </b><ul><li> indicates whether the Service has been tampered with</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_TAMPERED&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>TAMPERED&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>StatusLowBattery (79) </b><ul><li> indicates state of battery</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_LOW_BATTERY&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>LOW_BATTERY&nbsp(1)&nbsp;</b></li></ul></td></tr>
</table></details>
## InputSource (D9)
<details><summary> Defines an Input Source for a TV. Use <i>only</i> as a Linked Service for the <b>Television</b> Service.</summary><br><table>
<tr><th>Characteristic</th><th>Format</th><th>Perms</th><th>Min</th><th>Max</th><th>Constants/Defaults</th></tr>
<tr><td><b>ConfiguredName (E3) </b><ul><li> a "configurable" Service name - any updates made from within the Home App trigger an update in HomeSpan and vice versa.</li></ul></td><td align="center">string</td><td align="center">PW+PR+EV</td><td align="center">-</td><td align="center">-</td><td align="center">"unnamed"</td></tr>
<tr><td><b>IsConfigured (D6) </b><ul><li> indicates if a predefined Service has been configured</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_CONFIGURED&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>CONFIGURED&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>Identifier (E6) :small_blue_diamond:</b><ul><li> numerical Identifer of the <b>InputSource</b>.</li></ul></td><td align="center">uint32</td><td align="center">PR</td><td align="center">0</td><td align="center">255</td><td align="center">0</td></tr>
<tr><td><b>CurrentVisibilityState (135) </b><ul><li> current visibility of the Service, as selectable on the Settings Page of the Home App</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>VISIBLE&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>NOT_VISIBLE&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>TargetVisibilityState (134) </b><ul><li> indicates desired visibility of the Service, as selectable on the Settings Page of the Home App</li></ul></td><td align="center">uint8</td><td align="center">PW+PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>VISIBLE&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>NOT_VISIBLE&nbsp(1)&nbsp;</b></li></ul></td></tr>
</table></details>
## IrrigationSystem (CF)
<details><summary> Defines an Irrigation System. Linked Services: <b>Valve</b> Service (at least one <i>required</i>).</summary><br><table>
<tr><th>Characteristic</th><th>Format</th><th>Perms</th><th>Min</th><th>Max</th><th>Constants/Defaults</th></tr>
<tr><td><b>Active (B0) :small_blue_diamond:</b><ul><li> indicates if the Service is active/on</li></ul></td><td align="center">uint8</td><td align="center">PW+PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>INACTIVE&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>ACTIVE&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>ProgramMode (D1) :small_blue_diamond:</b><ul><li> indicates if pre-scheduled program is running</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">2</td><td><ul><li><b>NONE&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>SCHEDULED&nbsp(1)&nbsp;</b></li><li><b>SCHEDULE_OVERRIDEN&nbsp(2)&nbsp;</b></li></ul></td></tr>
<tr><td><b>InUse (D2) :small_blue_diamond:</b><ul><li> if Service is set to active, this indictes whether it is currently in use</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_IN_USE&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>IN_USE&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>RemainingDuration (D4) </b><ul><li> duration (in seconds) remaining for Service to be active/on</li></ul></td><td align="center">uint32</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">3600</td><td align="center">60</td></tr>
<tr><td><b>StatusFault (77) </b><ul><li> indicates whether the Service has a fault</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NO_FAULT&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>FAULT&nbsp(1)&nbsp;</b></li></ul></td></tr>
</table></details>
## LeakSensor (83)
<details><summary> Defines a Leak Sensor.</summary><br><table>
<tr><th>Characteristic</th><th>Format</th><th>Perms</th><th>Min</th><th>Max</th><th>Constants/Defaults</th></tr>
<tr><td><b>LeakDetected (70) :small_blue_diamond:</b><ul><li> indictates if a leak is detected</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_DETECTED&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>DETECTED&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>Name (23) </b><ul><li> default name of a Service used <i>only</i> during initial pairing</li></ul></td><td align="center">string</td><td align="center">PR</td><td align="center">-</td><td align="center">-</td><td align="center">"unnamed"</td></tr>
<tr><td><b>StatusActive (75) </b><ul><li> indicates whether the Service is properly functioning </li></ul></td><td align="center">bool</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_FUNCTIONING&nbsp(0)&nbsp;</b></li><li><b>FUNCTIONING&nbsp(1)&nbsp;</b>:heavy_check_mark:</li></ul></td></tr>
<tr><td><b>StatusFault (77) </b><ul><li> indicates whether the Service has a fault</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NO_FAULT&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>FAULT&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>StatusTampered (7A) </b><ul><li> indicates whether the Service has been tampered with</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_TAMPERED&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>TAMPERED&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>StatusLowBattery (79) </b><ul><li> indicates state of battery</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_LOW_BATTERY&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>LOW_BATTERY&nbsp(1)&nbsp;</b></li></ul></td></tr>
</table></details>
## LightBulb (43)
<details><summary> Defines any type of Light.</summary><br><table>
<tr><th>Characteristic</th><th>Format</th><th>Perms</th><th>Min</th><th>Max</th><th>Constants/Defaults</th></tr>
<tr><td><b>On (25) :small_blue_diamond:</b><ul><li> indicates if the Service is active/on</li></ul></td><td align="center">bool</td><td align="center">PR+PW+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>OFF&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>ON&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>Brightness (8) </b><ul><li> measured as a percentage</li></ul></td><td align="center">int</td><td align="center">PR+PW+EV</td><td align="center">0</td><td align="center">100</td><td align="center">0</td></tr>
<tr><td><b>Hue (13) </b><ul><li> color (in degrees) from red (0) to green (120) to blue (240) and back to red (360)</li></ul></td><td align="center">float</td><td align="center">PR+PW+EV</td><td align="center">0</td><td align="center">360</td><td align="center">0</td></tr>
<tr><td><b>Name (23) </b><ul><li> default name of a Service used <i>only</i> during initial pairing</li></ul></td><td align="center">string</td><td align="center">PR</td><td align="center">-</td><td align="center">-</td><td align="center">"unnamed"</td></tr>
<tr><td><b>Saturation (2F) </b><ul><li> color saturation, measured as a percentage</li></ul></td><td align="center">float</td><td align="center">PR+PW+EV</td><td align="center">0</td><td align="center">100</td><td align="center">0</td></tr>
<tr><td><b>ColorTemperature (CE) </b><ul><li> measured in inverse megaKelvin (= 1,000,000 / Kelvin)</li></ul></td><td align="center">uint32</td><td align="center">PR+PW+EV</td><td align="center">140</td><td align="center">500</td><td align="center">200</td></tr>
</table></details>
## LightSensor (84)
<details><summary> Defines a Light Sensor.</summary><br><table>
<tr><th>Characteristic</th><th>Format</th><th>Perms</th><th>Min</th><th>Max</th><th>Constants/Defaults</th></tr>
<tr><td><b>CurrentAmbientLightLevel (6B) :small_blue_diamond:</b><ul><li> measured in Lux (lumens/m<sup>2</sup></li></ul></td><td align="center">float</td><td align="center">PR+EV</td><td align="center">0.0001</td><td align="center">100000</td><td align="center">1</td></tr>
<tr><td><b>Name (23) </b><ul><li> default name of a Service used <i>only</i> during initial pairing</li></ul></td><td align="center">string</td><td align="center">PR</td><td align="center">-</td><td align="center">-</td><td align="center">"unnamed"</td></tr>
<tr><td><b>StatusActive (75) </b><ul><li> indicates whether the Service is properly functioning </li></ul></td><td align="center">bool</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_FUNCTIONING&nbsp(0)&nbsp;</b></li><li><b>FUNCTIONING&nbsp(1)&nbsp;</b>:heavy_check_mark:</li></ul></td></tr>
<tr><td><b>StatusFault (77) </b><ul><li> indicates whether the Service has a fault</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NO_FAULT&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>FAULT&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>StatusTampered (7A) </b><ul><li> indicates whether the Service has been tampered with</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_TAMPERED&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>TAMPERED&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>StatusLowBattery (79) </b><ul><li> indicates state of battery</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_LOW_BATTERY&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>LOW_BATTERY&nbsp(1)&nbsp;</b></li></ul></td></tr>
</table></details>
## LockMechanism (45)
<details><summary> Defines an electronic Lock.</summary><br><table>
<tr><th>Characteristic</th><th>Format</th><th>Perms</th><th>Min</th><th>Max</th><th>Constants/Defaults</th></tr>
<tr><td><b>LockCurrentState (1D) :small_blue_diamond:</b><ul><li> indicates state of a lock</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">3</td><td><ul><li><b>UNLOCKED&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>LOCKED&nbsp(1)&nbsp;</b></li><li><b>JAMMED&nbsp(2)&nbsp;</b></li><li><b>UNKNOWN&nbsp(3)&nbsp;</b></li></ul></td></tr>
<tr><td><b>LockTargetState (1E) :small_blue_diamond:</b><ul><li> indicates desired state of lock</li></ul></td><td align="center">uint8</td><td align="center">PW+PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>UNLOCK&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>LOCK&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>Name (23) </b><ul><li> default name of a Service used <i>only</i> during initial pairing</li></ul></td><td align="center">string</td><td align="center">PR</td><td align="center">-</td><td align="center">-</td><td align="center">"unnamed"</td></tr>
<tr><td><b>Mute (11A) :small_blue_diamond:</b><ul><li> not used</li></ul></td><td align="center">bool</td><td align="center">PW+PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>OFF&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>ON&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>Name (23) </b><ul><li> default name of a Service used <i>only</i> during initial pairing</li></ul></td><td align="center">string</td><td align="center">PR</td><td align="center">-</td><td align="center">-</td><td align="center">"unnamed"</td></tr>
<tr><td><b>Volume (119) </b><ul><li> unused</li></ul></td><td align="center">uint8</td><td align="center">PW+PR+EV</td><td align="center">0</td><td align="center">100</td><td align="center">0</td></tr>
</table></details>
## MotionSensor (85)
<details><summary> Defines a Motion Sensor.</summary><br><table>
<tr><th>Characteristic</th><th>Format</th><th>Perms</th><th>Min</th><th>Max</th><th>Constants/Defaults</th></tr>
<tr><td><b>MotionDetected (22) :small_blue_diamond:</b><ul><li> indicates if motion is detected</li></ul></td><td align="center">bool</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_DETECTED&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>DETECTED&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>Name (23) </b><ul><li> default name of a Service used <i>only</i> during initial pairing</li></ul></td><td align="center">string</td><td align="center">PR</td><td align="center">-</td><td align="center">-</td><td align="center">"unnamed"</td></tr>
<tr><td><b>StatusActive (75) </b><ul><li> indicates whether the Service is properly functioning </li></ul></td><td align="center">bool</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_FUNCTIONING&nbsp(0)&nbsp;</b></li><li><b>FUNCTIONING&nbsp(1)&nbsp;</b>:heavy_check_mark:</li></ul></td></tr>
<tr><td><b>StatusFault (77) </b><ul><li> indicates whether the Service has a fault</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NO_FAULT&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>FAULT&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>StatusTampered (7A) </b><ul><li> indicates whether the Service has been tampered with</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_TAMPERED&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>TAMPERED&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>StatusLowBattery (79) </b><ul><li> indicates state of battery</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_LOW_BATTERY&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>LOW_BATTERY&nbsp(1)&nbsp;</b></li></ul></td></tr>
</table></details>
## OccupancySensor (86)
<details><summary> Defines and Occupancy Sensor.</summary><br><table>
<tr><th>Characteristic</th><th>Format</th><th>Perms</th><th>Min</th><th>Max</th><th>Constants/Defaults</th></tr>
<tr><td><b>OccupancyDetected (71) :small_blue_diamond:</b><ul><li> indicates if occupanccy is detected</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_DETECTED&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>DETECTED&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>Name (23) </b><ul><li> default name of a Service used <i>only</i> during initial pairing</li></ul></td><td align="center">string</td><td align="center">PR</td><td align="center">-</td><td align="center">-</td><td align="center">"unnamed"</td></tr>
<tr><td><b>StatusActive (75) </b><ul><li> indicates whether the Service is properly functioning </li></ul></td><td align="center">bool</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_FUNCTIONING&nbsp(0)&nbsp;</b></li><li><b>FUNCTIONING&nbsp(1)&nbsp;</b>:heavy_check_mark:</li></ul></td></tr>
<tr><td><b>StatusFault (77) </b><ul><li> indicates whether the Service has a fault</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NO_FAULT&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>FAULT&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>StatusTampered (7A) </b><ul><li> indicates whether the Service has been tampered with</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_TAMPERED&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>TAMPERED&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>StatusLowBattery (79) </b><ul><li> indicates state of battery</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_LOW_BATTERY&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>LOW_BATTERY&nbsp(1)&nbsp;</b></li></ul></td></tr>
</table></details>
## Outlet (47)
<details><summary> Defines an controllable Outlet used to power any light or appliance.</summary><br><table>
<tr><th>Characteristic</th><th>Format</th><th>Perms</th><th>Min</th><th>Max</th><th>Constants/Defaults</th></tr>
<tr><td><b>On (25) :small_blue_diamond:</b><ul><li> indicates if the Service is active/on</li></ul></td><td align="center">bool</td><td align="center">PR+PW+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>OFF&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>ON&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>OutletInUse (26) :small_blue_diamond:</b><ul><li> indicates if an appliance or light is plugged into the outlet, regardless of whether on or off </li></ul></td><td align="center">bool</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_IN_USE&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>IN_USE&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>Name (23) </b><ul><li> default name of a Service used <i>only</i> during initial pairing</li></ul></td><td align="center">string</td><td align="center">PR</td><td align="center">-</td><td align="center">-</td><td align="center">"unnamed"</td></tr>
</table></details>
## SecuritySystem (7E)
<details><summary> Defines a Security System.</summary><br><table>
<tr><th>Characteristic</th><th>Format</th><th>Perms</th><th>Min</th><th>Max</th><th>Constants/Defaults</th></tr>
<tr><td><b>SecuritySystemCurrentState (66) :small_blue_diamond:</b><ul><li> indicates current state of the security system </li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">4</td><td><ul><li><b>ARMED_STAY&nbsp(0)&nbsp;</b></li><li><b>ARMED_AWAY&nbsp(1)&nbsp;</b></li><li><b>ARMED_NIGHT&nbsp(2)&nbsp;</b></li><li><b>DISARMED&nbsp(3)&nbsp;</b>:heavy_check_mark:</li><li><b>ALARM_TRIGGERED&nbsp(4)&nbsp;</b></li></ul></td></tr>
<tr><td><b>SecuritySystemTargetState (67) :small_blue_diamond:</b><ul><li> indicates desired state of the security system</li></ul></td><td align="center">uint8</td><td align="center">PW+PR+EV</td><td align="center">0</td><td align="center">3</td><td><ul><li><b>ARM_STAY&nbsp(0)&nbsp;</b></li><li><b>ARM_AWAY&nbsp(1)&nbsp;</b></li><li><b>ARM_NIGHT&nbsp(2)&nbsp;</b></li><li><b>DISARM&nbsp(3)&nbsp;</b>:heavy_check_mark:</li></ul></td></tr>
<tr><td><b>Name (23) </b><ul><li> default name of a Service used <i>only</i> during initial pairing</li></ul></td><td align="center">string</td><td align="center">PR</td><td align="center">-</td><td align="center">-</td><td align="center">"unnamed"</td></tr>
<tr><td><b>SecuritySystemAlarmType (8E) </b><ul><li> indicates whether alarm was triggered for known reason</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>KNOWN&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>UNKNOWN&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>StatusFault (77) </b><ul><li> indicates whether the Service has a fault</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NO_FAULT&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>FAULT&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>StatusTampered (7A) </b><ul><li> indicates whether the Service has been tampered with</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_TAMPERED&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>TAMPERED&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>ServiceLabelNamespace (CD) :small_blue_diamond:</b><ul><li> unused</li></ul></td><td align="center">uint8</td><td align="center">PR</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>DOTS&nbsp(0)&nbsp;</b></li><li><b>NUMERALS&nbsp(1)&nbsp;</b>:heavy_check_mark:</li></ul></td></tr>
</table></details>
## Slat (B9)
<details><summary> Defines a motorized ventilation Slat(s).</summary><br><table>
<tr><th>Characteristic</th><th>Format</th><th>Perms</th><th>Min</th><th>Max</th><th>Constants/Defaults</th></tr>
<tr><td><b>CurrentSlatState (AA) :small_blue_diamond:</b><ul><li> indicates current state of slats</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">2</td><td><ul><li><b>FIXED&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>JAMMED&nbsp(1)&nbsp;</b></li><li><b>SWINGING&nbsp(2)&nbsp;</b></li></ul></td></tr>
<tr><td><b>SlatType (C0) :small_blue_diamond:</b><ul><li> indicates the direction of a slat or group of slats</li></ul></td><td align="center">uint8</td><td align="center">PR</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>HORIZONTAL&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>VERTICAL&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>Name (23) </b><ul><li> default name of a Service used <i>only</i> during initial pairing</li></ul></td><td align="center">string</td><td align="center">PR</td><td align="center">-</td><td align="center">-</td><td align="center">"unnamed"</td></tr>
<tr><td><b>SwingMode (B6) </b><ul><li> indicates whether swing-nmode is enabled</li></ul></td><td align="center">uint8</td><td align="center">PR+EV+PW</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>SWING_DISABLED&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>SWING_ENABLED&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>CurrentTiltAngle (C1) </b><ul><li> current angle (in degrees) of slats from fully up or left (-90) to fully open (0) to fully down or right (90)</li></ul></td><td align="center">int</td><td align="center">PR+EV</td><td align="center">-90</td><td align="center">90</td><td align="center">0</td></tr>
<tr><td><b>TargetTiltAngle (C2) </b><ul><li> indicated desired angle (in degrees) of slats from fully up or left (-90) to fully open (0) to fully down or right (90) </li></ul></td><td align="center">int</td><td align="center">PW+PR+EV</td><td align="center">-90</td><td align="center">90</td><td align="center">0</td></tr>
</table></details>
## SmokeSensor (87)
<details><summary> Defines a Smoke Sensor.</summary><br><table>
<tr><th>Characteristic</th><th>Format</th><th>Perms</th><th>Min</th><th>Max</th><th>Constants/Defaults</th></tr>
<tr><td><b>SmokeDetected (76) :small_blue_diamond:</b><ul><li> indicates if smoke is detected</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_DETECTED&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>DETECTED&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>Name (23) </b><ul><li> default name of a Service used <i>only</i> during initial pairing</li></ul></td><td align="center">string</td><td align="center">PR</td><td align="center">-</td><td align="center">-</td><td align="center">"unnamed"</td></tr>
<tr><td><b>StatusActive (75) </b><ul><li> indicates whether the Service is properly functioning </li></ul></td><td align="center">bool</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_FUNCTIONING&nbsp(0)&nbsp;</b></li><li><b>FUNCTIONING&nbsp(1)&nbsp;</b>:heavy_check_mark:</li></ul></td></tr>
<tr><td><b>StatusFault (77) </b><ul><li> indicates whether the Service has a fault</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NO_FAULT&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>FAULT&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>StatusTampered (7A) </b><ul><li> indicates whether the Service has been tampered with</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_TAMPERED&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>TAMPERED&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>StatusLowBattery (79) </b><ul><li> indicates state of battery</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_LOW_BATTERY&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>LOW_BATTERY&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>Mute (11A) :small_blue_diamond:</b><ul><li> not used</li></ul></td><td align="center">bool</td><td align="center">PW+PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>OFF&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>ON&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>Name (23) </b><ul><li> default name of a Service used <i>only</i> during initial pairing</li></ul></td><td align="center">string</td><td align="center">PR</td><td align="center">-</td><td align="center">-</td><td align="center">"unnamed"</td></tr>
<tr><td><b>Volume (119) </b><ul><li> unused</li></ul></td><td align="center">uint8</td><td align="center">PW+PR+EV</td><td align="center">0</td><td align="center">100</td><td align="center">0</td></tr>
</table></details>
## StatelessProgrammableSwitch (89)
<details><summary> Defines a "Stateless" Programmable Switch that can be used to trigger actions in the Home App.</summary><br><table>
<tr><th>Characteristic</th><th>Format</th><th>Perms</th><th>Min</th><th>Max</th><th>Constants/Defaults</th></tr>
<tr><td><b>ProgrammableSwitchEvent (73) :small_blue_diamond:</b><ul><li> specifies type of button press</li></ul></td><td align="center">uint8</td><td align="center">PR+EV+NV</td><td align="center">0</td><td align="center">2</td><td><ul><li><b>SINGLE_PRESS&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>DOUBLE_PRESS&nbsp(1)&nbsp;</b></li><li><b>LONG_PRESS&nbsp(2)&nbsp;</b></li></ul></td></tr>
<tr><td><b>Name (23) </b><ul><li> default name of a Service used <i>only</i> during initial pairing</li></ul></td><td align="center">string</td><td align="center">PR</td><td align="center">-</td><td align="center">-</td><td align="center">"unnamed"</td></tr>
<tr><td><b>ServiceLabelIndex (CB) </b><ul><li> numerical index used to distinguish multiple copies of the same Service within an Accessory</li></ul></td><td align="center">uint8</td><td align="center">PR</td><td align="center">1</td><td align="center">255</td><td align="center">1</td></tr>
</table></details>
## Switch (49)
<details><summary> Defines a generic Switch.</summary><br><table>
<tr><th>Characteristic</th><th>Format</th><th>Perms</th><th>Min</th><th>Max</th><th>Constants/Defaults</th></tr>
<tr><td><b>On (25) :small_blue_diamond:</b><ul><li> indicates if the Service is active/on</li></ul></td><td align="center">bool</td><td align="center">PR+PW+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>OFF&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>ON&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>Name (23) </b><ul><li> default name of a Service used <i>only</i> during initial pairing</li></ul></td><td align="center">string</td><td align="center">PR</td><td align="center">-</td><td align="center">-</td><td align="center">"unnamed"</td></tr>
</table></details>
## Television (D8)
<details><summary> Defines a TV. Optional Linked Services: <b>InputSource</b> and <b>TelevisionSpeaker</b>.</summary><br><table>
<tr><th>Characteristic</th><th>Format</th><th>Perms</th><th>Min</th><th>Max</th><th>Constants/Defaults</th></tr>
<tr><td><b>Active (B0) :small_blue_diamond:</b><ul><li> indicates if the Service is active/on</li></ul></td><td align="center">uint8</td><td align="center">PW+PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>INACTIVE&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>ACTIVE&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>ConfiguredName (E3) </b><ul><li> a "configurable" Service name - any updates made from within the Home App trigger an update in HomeSpan and vice versa.</li></ul></td><td align="center">string</td><td align="center">PW+PR+EV</td><td align="center">-</td><td align="center">-</td><td align="center">"unnamed"</td></tr>
<tr><td><b>ActiveIdentifier (E7) </b><ul><li> numerical Identifier of the <b>InputSource</b> selected in the Home App.</li></ul></td><td align="center">uint32</td><td align="center">PW+PR+EV</td><td align="center">0</td><td align="center">255</td><td align="center">0</td></tr>
<tr><td><b>RemoteKey (E1) </b><ul><li> triggers an update when the corresponding key is pressed in the Remote Control widget on an iPhone </li></ul></td><td align="center">uint8</td><td align="center">PW</td><td align="center">4</td><td align="center">15</td><td><ul><li><b>UP&nbsp(4)&nbsp;</b></li><li><b>DOWN&nbsp(5)&nbsp;</b></li><li><b>LEFT&nbsp(6)&nbsp;</b></li><li><b>RIGHT&nbsp(7)&nbsp;</b></li><li><b>CENTER&nbsp(8)&nbsp;</b></li><li><b>BACK&nbsp(9)&nbsp;</b></li><li><b>PLAY_PAUSE&nbsp(11)&nbsp;</b></li><li><b>INFO&nbsp(15)&nbsp;</b></li></ul></td></tr>
<tr><td><b>PowerModeSelection (DF) </b><ul><li> when defined, creates a "View TV Settings" button in the Home App that triggers an update to this Characteristic when pressed </li></ul></td><td align="center">uint8</td><td align="center">PW</td><td align="center">0</td><td align="center">0</td><td><ul><li><b>VIEW_SETTINGS&nbsp(0)&nbsp;</b></li></ul></td></tr>
</table></details>
## TelevisionSpeaker (113)
<details><summary> Defines a Television Speaker that can be controlled via the Remote Control widget on an iPhone. Use <i>only</i> as a Linked Service for the <b>Television</b> Service.</summary><br><table>
<tr><th>Characteristic</th><th>Format</th><th>Perms</th><th>Min</th><th>Max</th><th>Constants/Defaults</th></tr>
<tr><td><b>VolumeControlType (E9) :small_blue_diamond:</b><ul><li> indicates the type of volume control</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">3</td><td><ul><li><b>NONE&nbsp(0)&nbsp;</b></li><li><b>RELATIVE&nbsp(1)&nbsp;</b></li><li><b>RELATIVE_CURRENT&nbsp(2)&nbsp;</b></li><li><b>ABSOLUTE&nbsp(3)&nbsp;</b>:heavy_check_mark:</li></ul></td></tr>
<tr><td><b>VolumeSelector (EA) :small_blue_diamond:</b><ul><li> triggered by presses to the iPhone's volume up/down buttons when TV is selected in the Remote Control widget</li></ul></td><td align="center">uint8</td><td align="center">PW</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>VOLUME_UP&nbsp(0)&nbsp;</b></li><li><b>VOLUME_DOWN&nbsp(1)&nbsp;</b></li></ul></td></tr>
</table></details>
## TemperatureSensor (8A)
<details><summary> Defines a Temperature Sensor.</summary><br><table>
<tr><th>Characteristic</th><th>Format</th><th>Perms</th><th>Min</th><th>Max</th><th>Constants/Defaults</th></tr>
<tr><td><b>CurrentTemperature (11) :small_blue_diamond:</b><ul><li> current temperature measured in Celsius</li></ul></td><td align="center">float</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">100</td><td align="center">0</td></tr>
<tr><td><b>Name (23) </b><ul><li> default name of a Service used <i>only</i> during initial pairing</li></ul></td><td align="center">string</td><td align="center">PR</td><td align="center">-</td><td align="center">-</td><td align="center">"unnamed"</td></tr>
<tr><td><b>StatusActive (75) </b><ul><li> indicates whether the Service is properly functioning </li></ul></td><td align="center">bool</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_FUNCTIONING&nbsp(0)&nbsp;</b></li><li><b>FUNCTIONING&nbsp(1)&nbsp;</b>:heavy_check_mark:</li></ul></td></tr>
<tr><td><b>StatusFault (77) </b><ul><li> indicates whether the Service has a fault</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NO_FAULT&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>FAULT&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>StatusTampered (7A) </b><ul><li> indicates whether the Service has been tampered with</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_TAMPERED&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>TAMPERED&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>StatusLowBattery (79) </b><ul><li> indicates state of battery</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_LOW_BATTERY&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>LOW_BATTERY&nbsp(1)&nbsp;</b></li></ul></td></tr>
</table></details>
## Thermostat (4A)
<details><summary> Defines a Thermostat used to control a furnace, air conditioner, or both.</summary><br><table>
<tr><th>Characteristic</th><th>Format</th><th>Perms</th><th>Min</th><th>Max</th><th>Constants/Defaults</th></tr>
<tr><td><b>CurrentHeatingCoolingState (F) :small_blue_diamond:</b><ul><li> indicates whether appliance is currently heating, cooling, or just idle</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">2</td><td><ul><li><b>IDLE&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>HEATING&nbsp(1)&nbsp;</b></li><li><b>COOLING&nbsp(2)&nbsp;</b></li></ul></td></tr>
<tr><td><b>TargetHeatingCoolingState (33) :small_blue_diamond:</b><ul><li> indicates desired state of appliance</li></ul></td><td align="center">uint8</td><td align="center">PW+PR+EV</td><td align="center">0</td><td align="center">3</td><td><ul><li><b>OFF&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>HEAT&nbsp(1)&nbsp;</b></li><li><b>COOL&nbsp(2)&nbsp;</b></li><li><b>AUTO&nbsp(3)&nbsp;</b></li></ul></td></tr>
<tr><td><b>CurrentTemperature (11) :small_blue_diamond:</b><ul><li> current temperature measured in Celsius</li></ul></td><td align="center">float</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">100</td><td align="center">0</td></tr>
<tr><td><b>TargetTemperature (35) :small_blue_diamond:</b><ul><li> indicates desired temperature measures in Celsius</li></ul></td><td align="center">float</td><td align="center">PW+PR+EV</td><td align="center">10</td><td align="center">38</td><td align="center">16</td></tr>
<tr><td><b>TemperatureDisplayUnits (36) :small_blue_diamond:</b><ul><li> indicates the desired units to display the temperature on the device itself (has no effect on Home App)</li></ul></td><td align="center">uint8</td><td align="center">PW+PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>CELSIUS&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>FAHRENHEIT&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>CoolingThresholdTemperature (D) </b><ul><li> cooling turns on when temperature (in Celsius) rises above this threshold</li></ul></td><td align="center">float</td><td align="center">PR+PW+EV</td><td align="center">10</td><td align="center">35</td><td align="center">10</td></tr>
<tr><td><b>CurrentRelativeHumidity (10) </b><ul><li> current humidity measured as a percentage</li></ul></td><td align="center">float</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">100</td><td align="center">0</td></tr>
<tr><td><b>HeatingThresholdTemperature (12) </b><ul><li> heating turns on when temperature (in Celsius) falls below this threshold</li></ul></td><td align="center">float</td><td align="center">PR+PW+EV</td><td align="center">0</td><td align="center">25</td><td align="center">16</td></tr>
<tr><td><b>Name (23) </b><ul><li> default name of a Service used <i>only</i> during initial pairing</li></ul></td><td align="center">string</td><td align="center">PR</td><td align="center">-</td><td align="center">-</td><td align="center">"unnamed"</td></tr>
<tr><td><b>TargetRelativeHumidity (34) </b><ul><li> indicates desired humidity measured as a percentage</li></ul></td><td align="center">float</td><td align="center">PW+PR+EV</td><td align="center">0</td><td align="center">100</td><td align="center">0</td></tr>
</table></details>
## Valve (D0)
<details><summary> Defines an electronic Valve. Can be used standalone or as a Linked Service in conjunction with the <b>Faucet</b> and <b>IrrigationSystem</b> Services.</summary><br><table>
<tr><th>Characteristic</th><th>Format</th><th>Perms</th><th>Min</th><th>Max</th><th>Constants/Defaults</th></tr>
<tr><td><b>Active (B0) :small_blue_diamond:</b><ul><li> indicates if the Service is active/on</li></ul></td><td align="center">uint8</td><td align="center">PW+PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>INACTIVE&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>ACTIVE&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>InUse (D2) :small_blue_diamond:</b><ul><li> if Service is set to active, this indictes whether it is currently in use</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_IN_USE&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>IN_USE&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>ValveType (D5) :small_blue_diamond:</b><ul><li> indicates the type of valve</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">3</td><td><ul><li><b>GENERIC&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>IRRIGATION&nbsp(1)&nbsp;</b></li><li><b>SHOWER_HEAD&nbsp(2)&nbsp;</b></li><li><b>FAUCET&nbsp(3)&nbsp;</b></li></ul></td></tr>
<tr><td><b>SetDuration (D3) </b><ul><li> specifies the duration (in seconds) for a Service to remain on once activated</li></ul></td><td align="center">uint32</td><td align="center">PW+PR+EV</td><td align="center">0</td><td align="center">3600</td><td align="center">60</td></tr>
<tr><td><b>RemainingDuration (D4) </b><ul><li> duration (in seconds) remaining for Service to be active/on</li></ul></td><td align="center">uint32</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">3600</td><td align="center">60</td></tr>
<tr><td><b>IsConfigured (D6) </b><ul><li> indicates if a predefined Service has been configured</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_CONFIGURED&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>CONFIGURED&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>ServiceLabelIndex (CB) </b><ul><li> numerical index used to distinguish multiple copies of the same Service within an Accessory</li></ul></td><td align="center">uint8</td><td align="center">PR</td><td align="center">1</td><td align="center">255</td><td align="center">1</td></tr>
<tr><td><b>StatusFault (77) </b><ul><li> indicates whether the Service has a fault</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NO_FAULT&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>FAULT&nbsp(1)&nbsp;</b></li></ul></td></tr>
<tr><td><b>Name (23) </b><ul><li> default name of a Service used <i>only</i> during initial pairing</li></ul></td><td align="center">string</td><td align="center">PR</td><td align="center">-</td><td align="center">-</td><td align="center">"unnamed"</td></tr>
</table></details>
## Window (8B)
<details><summary> Defines a motorized Window.</summary><br><table>
<tr><th>Characteristic</th><th>Format</th><th>Perms</th><th>Min</th><th>Max</th><th>Constants/Defaults</th></tr>
<tr><td><b>CurrentPosition (6D) :small_blue_diamond:</b><ul><li> current position (as a percentage) from fully closed (0) to full open (100)</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">100</td><td align="center">0</td></tr>
<tr><td><b>TargetPosition (7C) :small_blue_diamond:</b><ul><li> indicates target position (as a percentage) from fully closed (0) to full open (100)</li></ul></td><td align="center">uint8</td><td align="center">PW+PR+EV</td><td align="center">0</td><td align="center">100</td><td align="center">0</td></tr>
<tr><td><b>Name (23) </b><ul><li> default name of a Service used <i>only</i> during initial pairing</li></ul></td><td align="center">string</td><td align="center">PR</td><td align="center">-</td><td align="center">-</td><td align="center">"unnamed"</td></tr>
<tr><td><b>ObstructionDetected (24) </b><ul><li> indicates if obstruction is detected</li></ul></td><td align="center">bool</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_DETECTED&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>DETECTED&nbsp(1)&nbsp;</b></li></ul></td></tr>
</table></details>
## WindowCovering (8C)
<details><summary> Defines a motorized Window Shade, Screen, Awning, etc.</summary><br><table>
<tr><th>Characteristic</th><th>Format</th><th>Perms</th><th>Min</th><th>Max</th><th>Constants/Defaults</th></tr>
<tr><td><b>TargetPosition (7C) :small_blue_diamond:</b><ul><li> indicates target position (as a percentage) from fully closed (0) to full open (100)</li></ul></td><td align="center">uint8</td><td align="center">PW+PR+EV</td><td align="center">0</td><td align="center">100</td><td align="center">0</td></tr>
<tr><td><b>CurrentPosition (6D) :small_blue_diamond:</b><ul><li> current position (as a percentage) from fully closed (0) to full open (100)</li></ul></td><td align="center">uint8</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">100</td><td align="center">0</td></tr>
<tr><td><b>Name (23) </b><ul><li> default name of a Service used <i>only</i> during initial pairing</li></ul></td><td align="center">string</td><td align="center">PR</td><td align="center">-</td><td align="center">-</td><td align="center">"unnamed"</td></tr>
<tr><td><b>CurrentHorizontalTiltAngle (6C) </b><ul><li> current angle (in degrees) of slats from fully up (-90) to fully open (0) to fully down (90) </li></ul></td><td align="center">int</td><td align="center">PR+EV</td><td align="center">-90</td><td align="center">90</td><td align="center">0</td></tr>
<tr><td><b>TargetHorizontalTiltAngle (7B) </b><ul><li> indicates desired angle (in degrees) of slats from fully up (-90) to fully open (0) to fully down (90)</li></ul></td><td align="center">int</td><td align="center">PW+PR+EV</td><td align="center">-90</td><td align="center">90</td><td align="center">0</td></tr>
<tr><td><b>CurrentVerticalTiltAngle (6E) </b><ul><li> current angle (in degrees) of slats from fully left (-90) to fully open (0) to fully right (90)</li></ul></td><td align="center">int</td><td align="center">PR+EV</td><td align="center">-90</td><td align="center">90</td><td align="center">0</td></tr>
<tr><td><b>TargetVerticalTiltAngle (7D) </b><ul><li> indicates desired angle (in degrees) of slats from fully left (-90) to fully open (0) to fully right (90)</li></ul></td><td align="center">int</td><td align="center">PW+PR+EV</td><td align="center">-90</td><td align="center">90</td><td align="center">0</td></tr>
<tr><td><b>ObstructionDetected (24) </b><ul><li> indicates if obstruction is detected</li></ul></td><td align="center">bool</td><td align="center">PR+EV</td><td align="center">0</td><td align="center">1</td><td><ul><li><b>NOT_DETECTED&nbsp(0)&nbsp;</b>:heavy_check_mark:</li><li><b>DETECTED&nbsp(1)&nbsp;</b></li></ul></td></tr>
</table></details>
---
[↩️](../README.md) Back to the Welcome page

View File

@ -118,8 +118,7 @@ struct DEV_WindowShade : Service::WindowCovering { // A motorized Window Sha
// the current state.
// According to HAP, the Characteristic Position State is also required. However, this seems duplicative and is NOT needed
// at all given the way HomeKit uses current position. HomeSpan will warn you if Position State is not defined (since it
// is technically required) but this works fine without it.
// at all given the way HomeKit uses current position.
} // loop

View File

@ -32,15 +32,23 @@
// Macros to define services, along with vectors of required and optional characteristics for each Span Service structure
// The names of the macros are picked up by external scripts to help generate documentation
// Note: These macros below are also parsed by an external awk script to auto-generate Services and Characteristics documentation.
//
// The CREATE_SERV_DEP() macro is the same as the CREATE_SERV() macro, except that it is used for deprecated Services that will not
// be included in documentation. The OPT_DEP() macro is that same as the OPT() macro, except that it is used for deprecated Characteristics
// that will not be included in documentation.
#define CREATE_SERV(NAME,UUID) struct NAME : SpanService { NAME() : SpanService{#UUID,#NAME}{
#define CREATE_SERV_DEP(NAME,UUID) struct NAME : SpanService { NAME() : SpanService{#UUID,#NAME}{
#define END_SERV }};
#define REQ(HAPCHAR) req.push_back(&hapChars.HAPCHAR)
#define OPT(HAPCHAR) opt.push_back(&hapChars.HAPCHAR)
#define OPT_DEP(HAPCHAR) opt.push_back(&hapChars.HAPCHAR)
namespace Service {
CREATE_SERV(AccessoryInformation,3E)
CREATE_SERV(AccessoryInformation,3E) // Required Identification Information. For each Accessory in a HomeSpan device this <i>must</i> be included as the first Service.
REQ(Identify);
OPT(FirmwareRevision);
OPT(Manufacturer);
@ -48,10 +56,10 @@ namespace Service {
OPT(Name);
OPT(SerialNumber);
OPT(HardwareRevision);
OPT(AccessoryFlags);
OPT_DEP(AccessoryFlags);
END_SERV
CREATE_SERV(AirPurifier,BB)
CREATE_SERV(AirPurifier,BB) // Defines a basic Air Purifier with an optional fan. Optional Linked Services: <b>FilterMaintenance</b>, <b>AirQualitySensor</b>, <b>Fan</b>, and <b>Slat</b>
REQ(Active);
REQ(CurrentAirPurifierState);
REQ(TargetAirPurifierState);
@ -61,7 +69,7 @@ namespace Service {
OPT(LockPhysicalControls);
END_SERV
CREATE_SERV(AirQualitySensor,8D)
CREATE_SERV(AirQualitySensor,8D) // Defines an Air Quality Sensor.
REQ(AirQuality);
OPT(Name);
OPT(OzoneDensity);
@ -76,14 +84,14 @@ namespace Service {
OPT(StatusLowBattery);
END_SERV
CREATE_SERV(BatteryService,96)
CREATE_SERV(BatteryService,96) // Defines a standalone Battery Service.
REQ(BatteryLevel);
REQ(ChargingState);
REQ(StatusLowBattery);
OPT(Name);
END_SERV
CREATE_SERV(CarbonDioxideSensor,97)
CREATE_SERV(CarbonDioxideSensor,97) // Defines a Carbon Dioxide Sensor.
REQ(CarbonDioxideDetected);
OPT(Name);
OPT(StatusActive);
@ -94,7 +102,7 @@ namespace Service {
OPT(CarbonDioxidePeakLevel);
END_SERV
CREATE_SERV(CarbonMonoxideSensor,7F)
CREATE_SERV(CarbonMonoxideSensor,7F) // Defines a Carbon Monoxide Sensor.
REQ(CarbonMonoxideDetected);
OPT(Name);
OPT(StatusActive);
@ -105,7 +113,7 @@ namespace Service {
OPT(CarbonMonoxidePeakLevel);
END_SERV
CREATE_SERV(ContactSensor,80)
CREATE_SERV(ContactSensor,80) // Defines a Contact Sensor.
REQ(ContactSensorState);
OPT(Name);
OPT(StatusActive);
@ -114,23 +122,23 @@ namespace Service {
OPT(StatusLowBattery);
END_SERV
CREATE_SERV(Door,81)
CREATE_SERV(Door,81) // Defines a motorized Door.
REQ(CurrentPosition);
REQ(TargetPosition);
REQ(PositionState);
OPT_DEP(PositionState);
OPT(Name);
OPT(HoldPosition);
OPT_DEP(HoldPosition);
OPT(ObstructionDetected);
END_SERV
CREATE_SERV(Doorbell,121)
CREATE_SERV(Doorbell,121) // Defines a Doorbell. Can be used on a standalone basis or in conjunction with a <b>LockMechanism</b> Service.
REQ(ProgrammableSwitchEvent);
OPT(Name);
OPT(Volume);
OPT(Brightness);
OPT_DEP(Volume);
OPT_DEP(Brightness);
END_SERV
CREATE_SERV(Fan,B7)
CREATE_SERV(Fan,B7) // Defines a Fan. Can be used in conjunction with a <b>LightBulb</b> Service to create a Lighted Ceiling Fan.
REQ(Active);
OPT(Name);
OPT(CurrentFanState);
@ -141,20 +149,20 @@ namespace Service {
OPT(LockPhysicalControls);
END_SERV
CREATE_SERV(Faucet,D7)
CREATE_SERV(Faucet,D7) // Defines the master control for a multi-Valve appliance. Linked Services: <b>Valve</b> (at least one <i>required</i>), and <b>HeaterCooler</b> (optional).
REQ(Active);
OPT(StatusFault);
OPT(Name);
END_SERV
CREATE_SERV(FilterMaintenance,BA)
CREATE_SERV(FilterMaintenance,BA) // Defines a Filter Maintainence check.
REQ(FilterChangeIndication);
OPT(Name);
OPT(FilterLifeLevel);
OPT(ResetFilterIndication);
END_SERV
CREATE_SERV(GarageDoorOpener,41)
CREATE_SERV(GarageDoorOpener,41) // Defines a motorized Garage Door Opener.
REQ(CurrentDoorState);
REQ(TargetDoorState);
REQ(ObstructionDetected);
@ -163,11 +171,11 @@ namespace Service {
OPT(Name);
END_SERV
CREATE_SERV(HAPProtocolInformation,A2)
CREATE_SERV_DEP(HAPProtocolInformation,A2)
REQ(Version);
END_SERV
CREATE_SERV(HeaterCooler,BC)
CREATE_SERV(HeaterCooler,BC) // Defines a standalone Heater, Cooler, or combined Heater/Cooler. Can be used with a separate <b>Fan</b> Service and/or <b>Slat</b> Service to extend functionality.
REQ(Active);
REQ(CurrentTemperature);
REQ(CurrentHeaterCoolerState);
@ -181,7 +189,7 @@ namespace Service {
OPT(LockPhysicalControls);
END_SERV
CREATE_SERV(HumidifierDehumidifier,BD)
CREATE_SERV(HumidifierDehumidifier,BD) // Defines a Humidifer, Dehumidifier, or combined Humidifer/Dehumidifier. Can be used with a separate <b>Fan</b> Service and/or <b>Slat</b> Service to extend functionality.
REQ(Active);
REQ(CurrentRelativeHumidity);
REQ(CurrentHumidifierDehumidifierState);
@ -195,7 +203,7 @@ namespace Service {
OPT(LockPhysicalControls);
END_SERV
CREATE_SERV(HumiditySensor,82)
CREATE_SERV(HumiditySensor,82) // Defines a Humidity Sensor.
REQ(CurrentRelativeHumidity);
OPT(Name);
OPT(StatusActive);
@ -204,7 +212,7 @@ namespace Service {
OPT(StatusLowBattery);
END_SERV
CREATE_SERV(InputSource,D9)
CREATE_SERV(InputSource,D9) // Defines an Input Source for a TV. Use <i>only</i> as a Linked Service for the <b>Television</b> Service.
OPT(ConfiguredName);
OPT(IsConfigured);
REQ(Identifier);
@ -212,7 +220,7 @@ namespace Service {
OPT(TargetVisibilityState);
END_SERV
CREATE_SERV(IrrigationSystem,CF)
CREATE_SERV(IrrigationSystem,CF) // Defines an Irrigation System. Linked Services: <b>Valve</b> Service (at least one <i>required</i>).
REQ(Active);
REQ(ProgramMode);
REQ(InUse);
@ -220,7 +228,7 @@ namespace Service {
OPT(StatusFault);
END_SERV
CREATE_SERV(LeakSensor,83)
CREATE_SERV(LeakSensor,83) // Defines a Leak Sensor.
REQ(LeakDetected);
OPT(Name);
OPT(StatusActive);
@ -229,7 +237,7 @@ namespace Service {
OPT(StatusLowBattery);
END_SERV
CREATE_SERV(LightBulb,43)
CREATE_SERV(LightBulb,43) // Defines any type of Light.
REQ(On);
OPT(Brightness);
OPT(Hue);
@ -238,7 +246,7 @@ namespace Service {
OPT(ColorTemperature);
END_SERV
CREATE_SERV(LightSensor,84)
CREATE_SERV(LightSensor,84) // Defines a Light Sensor.
REQ(CurrentAmbientLightLevel);
OPT(Name);
OPT(StatusActive);
@ -247,19 +255,19 @@ namespace Service {
OPT(StatusLowBattery);
END_SERV
CREATE_SERV(LockMechanism,45)
CREATE_SERV(LockMechanism,45) // Defines an electronic Lock.
REQ(LockCurrentState);
REQ(LockTargetState);
OPT(Name);
END_SERV
CREATE_SERV(Microphone,112)
CREATE_SERV_DEP(Microphone,112)
REQ(Mute);
OPT(Name);
OPT(Volume);
END_SERV
CREATE_SERV(MotionSensor,85)
CREATE_SERV(MotionSensor,85) // Defines a Motion Sensor.
REQ(MotionDetected);
OPT(Name);
OPT(StatusActive);
@ -268,7 +276,7 @@ namespace Service {
OPT(StatusLowBattery);
END_SERV
CREATE_SERV(OccupancySensor,86)
CREATE_SERV(OccupancySensor,86) // Defines and Occupancy Sensor.
REQ(OccupancyDetected);
OPT(Name);
OPT(StatusActive);
@ -277,13 +285,13 @@ namespace Service {
OPT(StatusLowBattery);
END_SERV
CREATE_SERV(Outlet,47)
CREATE_SERV(Outlet,47) // Defines an controllable Outlet used to power any light or appliance.
REQ(On);
REQ(OutletInUse);
OPT(Name);
END_SERV
CREATE_SERV(SecuritySystem,7E)
CREATE_SERV(SecuritySystem,7E) // Defines a Security System.
REQ(SecuritySystemCurrentState);
REQ(SecuritySystemTargetState);
OPT(Name);
@ -292,11 +300,11 @@ namespace Service {
OPT(StatusTampered);
END_SERV
CREATE_SERV(ServiceLabel,CC)
CREATE_SERV_DEP(ServiceLabel,CC)
REQ(ServiceLabelNamespace);
END_SERV
CREATE_SERV(Slat,B9)
CREATE_SERV(Slat,B9) // Defines a motorized ventilation Slat(s).
REQ(CurrentSlatState);
REQ(SlatType);
OPT(Name);
@ -305,7 +313,7 @@ namespace Service {
OPT(TargetTiltAngle);
END_SERV
CREATE_SERV(SmokeSensor,87)
CREATE_SERV(SmokeSensor,87) // Defines a Smoke Sensor.
REQ(SmokeDetected);
OPT(Name);
OPT(StatusActive);
@ -314,24 +322,24 @@ namespace Service {
OPT(StatusLowBattery);
END_SERV
CREATE_SERV(Speaker,113)
CREATE_SERV_DEP(Speaker,113)
REQ(Mute);
OPT(Name);
OPT(Volume);
END_SERV
CREATE_SERV(StatelessProgrammableSwitch,89)
CREATE_SERV(StatelessProgrammableSwitch,89) // Defines a "Stateless" Programmable Switch that can be used to trigger actions in the Home App.
REQ(ProgrammableSwitchEvent);
OPT(Name);
OPT(ServiceLabelIndex);
END_SERV
CREATE_SERV(Switch,49)
CREATE_SERV(Switch,49) // Defines a generic Switch.
REQ(On);
OPT(Name);
END_SERV
CREATE_SERV(Television,D8)
CREATE_SERV(Television,D8) // Defines a TV. Optional Linked Services: <b>InputSource</b> and <b>TelevisionSpeaker</b>.
REQ(Active);
OPT(ConfiguredName);
OPT(ActiveIdentifier);
@ -339,12 +347,12 @@ namespace Service {
OPT(PowerModeSelection);
END_SERV
CREATE_SERV(TelevisionSpeaker,113)
CREATE_SERV(TelevisionSpeaker,113) // Defines a Television Speaker that can be controlled via the Remote Control widget on an iPhone. Use <i>only</i> as a Linked Service for the <b>Television</b> Service.
REQ(VolumeControlType);
REQ(VolumeSelector);
END_SERV
CREATE_SERV(TemperatureSensor,8A)
CREATE_SERV(TemperatureSensor,8A) // Defines a Temperature Sensor.
REQ(CurrentTemperature);
OPT(Name);
OPT(StatusActive);
@ -353,7 +361,7 @@ namespace Service {
OPT(StatusLowBattery);
END_SERV
CREATE_SERV(Thermostat,4A)
CREATE_SERV(Thermostat,4A) // Defines a Thermostat used to control a furnace, air conditioner, or both.
REQ(CurrentHeatingCoolingState);
REQ(TargetHeatingCoolingState);
REQ(CurrentTemperature);
@ -366,7 +374,7 @@ namespace Service {
OPT(TargetRelativeHumidity);
END_SERV
CREATE_SERV(Valve,D0)
CREATE_SERV(Valve,D0) // Defines an electronic Valve. Can be used standalone or as a Linked Service in conjunction with the <b>Faucet</b> and <b>IrrigationSystem</b> Services.
REQ(Active);
REQ(InUse);
REQ(ValveType);
@ -378,21 +386,21 @@ namespace Service {
OPT(Name);
END_SERV
CREATE_SERV(Window,8B)
CREATE_SERV(Window,8B) // Defines a motorized Window.
REQ(CurrentPosition);
REQ(TargetPosition);
REQ(PositionState);
OPT_DEP(PositionState);
OPT(Name);
OPT(HoldPosition);
OPT_DEP(HoldPosition);
OPT(ObstructionDetected);
END_SERV
CREATE_SERV(WindowCovering,8C)
CREATE_SERV(WindowCovering,8C) // Defines a motorized Window Shade, Screen, Awning, etc.
REQ(TargetPosition);
REQ(CurrentPosition);
REQ(PositionState);
OPT_DEP(PositionState);
OPT(Name);
OPT(HoldPosition);
OPT_DEP(HoldPosition);
OPT(CurrentHorizontalTiltAngle);
OPT(TargetHorizontalTiltAngle);
OPT(CurrentVerticalTiltAngle);
@ -413,122 +421,122 @@ namespace Service {
namespace Characteristic {
CREATE_CHAR(uint32_t,AccessoryFlags,1,1,1);
CREATE_CHAR(uint8_t,Active,0,0,1,INACTIVE,ACIVE);
CREATE_CHAR(uint32_t,ActiveIdentifier,0,0,255);
CREATE_CHAR(uint8_t,AirQuality,0,0,5,UNKNOWN,EXCELLENT,GOOD,FAIR,INFERIOR,POOR);
CREATE_CHAR(uint8_t,BatteryLevel,0,0,100);
CREATE_CHAR(int,Brightness,0,0,100);
CREATE_CHAR(double,CarbonMonoxideLevel,0,0,100);
CREATE_CHAR(double,CarbonMonoxidePeakLevel,0,0,100);
CREATE_CHAR(uint8_t,CarbonMonoxideDetected,0,0,1,NORMAL,ABNORMAL);
CREATE_CHAR(double,CarbonDioxideLevel,0,0,100000);
CREATE_CHAR(double,CarbonDioxidePeakLevel,0,0,100000);
CREATE_CHAR(uint8_t,CarbonDioxideDetected,0,0,1,NORMAL,ABNORMAL);
CREATE_CHAR(uint8_t,ChargingState,0,0,2,NOT_CHARGING,CHARGING,NOT_CHARGEABLE);
CREATE_CHAR(uint8_t,ClosedCaptions,0,0,1);
CREATE_CHAR(double,CoolingThresholdTemperature,10,10,35);
CREATE_CHAR(uint32_t,ColorTemperature,200,140,500);
CREATE_CHAR(uint8_t,ContactSensorState,1,0,1,DETECTED,NOT_DETECTED);
CREATE_CHAR(const char *,ConfiguredName,"unnamed",0,1);
CREATE_CHAR(double,CurrentAmbientLightLevel,1,0.0001,100000);
CREATE_CHAR(int,CurrentHorizontalTiltAngle,0,-90,90);
CREATE_CHAR(uint8_t,CurrentAirPurifierState,1,0,2,INACTIVE,IDLE,PURIFYING);
CREATE_CHAR(uint8_t,CurrentSlatState,0,0,2,FIXED,JAMMED,SWINGING);
CREATE_CHAR(uint8_t,CurrentPosition,0,0,100);
CREATE_CHAR(int,CurrentVerticalTiltAngle,0,-90,90);
CREATE_CHAR(uint8_t,CurrentVisibilityState,0,0,1);
CREATE_CHAR(uint8_t,CurrentHumidifierDehumidifierState,1,0,3,INACTIVE,IDLE,HUMIDIFYING,DEHUMIDIFYING);
CREATE_CHAR(uint8_t,CurrentDoorState,1,0,4,OPEN,CLOSED,OPENING,CLOSING,STOPPED);
CREATE_CHAR(uint8_t,CurrentFanState,1,0,2,INACTIVE,IDLE,BLOWING);
CREATE_CHAR(uint8_t,CurrentHeatingCoolingState,0,0,2,OFF,HEATING,COOLING);
CREATE_CHAR(uint8_t,CurrentHeaterCoolerState,1,0,3,INACTIVE,IDLE,HEATING,COOLING);
CREATE_CHAR(uint8_t,CurrentMediaState,0,0,5);
CREATE_CHAR(double,CurrentRelativeHumidity,0,0,100);
CREATE_CHAR(double,CurrentTemperature,0,0,100);
CREATE_CHAR(int,CurrentTiltAngle,0,-90,90);
CREATE_CHAR(double,FilterLifeLevel,0,0,100);
CREATE_CHAR(uint8_t,FilterChangeIndication,0,0,1,NO_CHANGE_NEEDED,CHANGE_NEEDED);
CREATE_CHAR(const char *,FirmwareRevision,"1.0.0",0,1);
CREATE_CHAR(const char *,HardwareRevision,"1.0.0",0,1);
CREATE_CHAR(double,HeatingThresholdTemperature,16,0,25);
CREATE_CHAR(boolean,HoldPosition,false,0,1);
CREATE_CHAR(double,Hue,0,0,360);
CREATE_CHAR(boolean,Identify,false,0,1);
CREATE_CHAR(uint32_t,Identifier,0,0,255);
CREATE_CHAR(uint8_t,InputDeviceType,0,0,6);
CREATE_CHAR(uint8_t,InputSourceType,0,0,10);
CREATE_CHAR(uint8_t,InUse,0,0,1,NOT_IN_USE,IN_USE);
CREATE_CHAR(uint8_t,IsConfigured,0,0,1,NOT_CONFIGURED,CONFIGURED);
CREATE_CHAR(uint8_t,LeakDetected,0,0,1,NOT_DETECTED,DETECTED);
CREATE_CHAR(uint8_t,LockCurrentState,0,0,3,UNLOCKED,LOCKED,JAMMED,UNKNOWN);
CREATE_CHAR(uint8_t,LockPhysicalControls,0,0,1,CONTROL_LOCK_DISABLED,CONTROL_LOCK_ENABLED);
CREATE_CHAR(uint8_t,LockTargetState,0,0,1,UNLOCK,LOCK);
CREATE_CHAR(const char *,Manufacturer,"HomeSpan",0,1);
CREATE_CHAR(const char *,Model,"HomeSpan-ESP32",0,1);
CREATE_CHAR(boolean,MotionDetected,false,0,1);
CREATE_CHAR(boolean,Mute,false,0,1,OFF,ON);
CREATE_CHAR(const char *,Name,"unnamed",0,1);
CREATE_CHAR(double,NitrogenDioxideDensity,0,0,1000);
CREATE_CHAR(boolean,ObstructionDetected,false,0,1);
CREATE_CHAR(double,PM25Density,0,0,1000);
CREATE_CHAR(uint8_t,OccupancyDetected,0,0,1,NOT_DETECTED,DETECTED);
CREATE_CHAR(boolean,OutletInUse,false,0,1);
CREATE_CHAR(boolean,On,false,0,1);
CREATE_CHAR(double,OzoneDensity,0,0,1000);
CREATE_CHAR(uint8_t,PictureMode,0,0,13);
CREATE_CHAR(double,PM10Density,0,0,1000);
CREATE_CHAR(uint8_t,PositionState,2,0,2,GOING_TO_MINIMUM,GOING_TO_MAXIMUM,STOPPED);
CREATE_CHAR(uint8_t,PowerModeSelection,0,0,1);
CREATE_CHAR(uint8_t,ProgramMode,0,0,2,NONE,SCHEDULED,SCHEDULE_OVERRIDEN);
CREATE_CHAR(uint8_t,ProgrammableSwitchEvent,0,0,2,SINGLE_PRESS,DOUBLE_PRESS,LONG_PRESS);
CREATE_CHAR(double,RelativeHumidityDehumidifierThreshold,50,0,100);
CREATE_CHAR(double,RelativeHumidityHumidifierThreshold,50,0,100);
CREATE_CHAR(uint32_t,RemainingDuration,60,0,3600);
CREATE_CHAR(uint8_t,RemoteKey,0,0,16);
CREATE_CHAR(uint8_t,ResetFilterIndication,0,1,1);
CREATE_CHAR(int,RotationDirection,0,0,1,CLOCKWISE,COUNTERCLOCKWISE);
CREATE_CHAR(double,RotationSpeed,0,0,100);
CREATE_CHAR(double,Saturation,0,0,100);
CREATE_CHAR(uint8_t,SecuritySystemAlarmType,0,0,1,KNOWN,UNKNOWN);
CREATE_CHAR(uint8_t,SecuritySystemCurrentState,3,0,4,ARMED_STAY,ARMED_AWAY,ARMED_NIGHT,DISARMED,ALARM_TRIGGERED);
CREATE_CHAR(uint8_t,SecuritySystemTargetState,3,0,3,ARM_STAY,ARM_AWAY,ARM_NIGHT,DISARM);
CREATE_CHAR(const char *,SerialNumber,"HS-12345",0,1);
CREATE_CHAR(uint8_t,ServiceLabelIndex,1,1,255);
CREATE_CHAR(uint8_t,ServiceLabelNamespace,1,0,1,DOTS,NUMERALS);
CREATE_CHAR(uint8_t,SlatType,0,0,1,HORIZONTAL,VERTICAL);
CREATE_CHAR(uint8_t,SleepDiscoveryMode,0,0,1);
CREATE_CHAR(uint8_t,SmokeDetected,0,0,1,NOT_DETECTED,DETECTED);
CREATE_CHAR(boolean,StatusActive,true,0,1);
CREATE_CHAR(uint8_t,StatusFault,0,0,1,NO_FAULT,FAULT);
CREATE_CHAR(uint8_t,StatusJammed,0,0,1,NOT_JAMMED,JAMMED);
CREATE_CHAR(uint8_t,StatusLowBattery,0,0,1,NOT_LOW_BATTERY,LOW_BATTERY);
CREATE_CHAR(uint8_t,StatusTampered,0,0,1,NOT_TAMPERED,TAMPERED);
CREATE_CHAR(double,SulphurDioxideDensity,0,0,1000);
CREATE_CHAR(uint8_t,SwingMode,0,0,1,SWING_DISABLED,SWING_ENABLED);
CREATE_CHAR(uint8_t,TargetAirPurifierState,1,0,1,MANUAL,AUTO);
CREATE_CHAR(uint8_t,TargetFanState,1,0,1,MANUAL,AUTO);
CREATE_CHAR(int,TargetTiltAngle,0,-90,90);
CREATE_CHAR(uint8_t,TargetHeaterCoolerState,0,0,2,AUTO,HEAT,COOL);
CREATE_CHAR(uint32_t,SetDuration,60,0,3600);
CREATE_CHAR(int,TargetHorizontalTiltAngle,0,-90,90);
CREATE_CHAR(uint8_t,TargetHumidifierDehumidifierState,0,0,2,AUTO,HUMIDIFY,DEHUMIDIFY);
CREATE_CHAR(uint8_t,TargetPosition,0,0,100);
CREATE_CHAR(uint8_t,TargetDoorState,1,0,1,OPEN,CLOSED);
CREATE_CHAR(uint8_t,TargetHeatingCoolingState,0,0,3,OFF,HEAT,COOL,AUTO);
CREATE_CHAR(uint8_t,TargetMediaState,0,0,2);
CREATE_CHAR(double,TargetRelativeHumidity,0,0,100);
CREATE_CHAR(double,TargetTemperature,16,10,38);
CREATE_CHAR(uint8_t,TargetVisibilityState,0,0,1);
CREATE_CHAR(uint8_t,TemperatureDisplayUnits,0,0,1,CELSIUS,FAHRENHEIT);
CREATE_CHAR(int,TargetVerticalTiltAngle,0,-90,90);
CREATE_CHAR(uint8_t,ValveType,0,0,3);
CREATE_CHAR(const char *,Version,"1.0.0",0,1);
CREATE_CHAR(double,VOCDensity,0,0,1000);
CREATE_CHAR(uint8_t,Volume,0,0,100);
CREATE_CHAR(uint8_t,VolumeControlType,0,0,3);
CREATE_CHAR(uint8_t,VolumeSelector,0,0,1);
CREATE_CHAR(double,WaterLevel,0,0,100);
CREATE_CHAR(uint32_t,AccessoryFlags,1,1,1); // not applicable for HomeSpan
CREATE_CHAR(uint8_t,Active,0,0,1,INACTIVE,ACTIVE); // indicates if the Service is active/on
CREATE_CHAR(uint32_t,ActiveIdentifier,0,0,255); // numerical Identifier of the <b>InputSource</b> selected in the Home App.
CREATE_CHAR(uint8_t,AirQuality,0,0,5,UNKNOWN,EXCELLENT,GOOD,FAIR,INFERIOR,POOR); // a subjective description
CREATE_CHAR(uint8_t,BatteryLevel,100,0,100); // measured as a percentage
CREATE_CHAR(int,Brightness,0,0,100); // measured as a percentage
CREATE_CHAR(double,CarbonMonoxideLevel,0,0,100); // measured in parts per million (ppm)
CREATE_CHAR(double,CarbonMonoxidePeakLevel,0,0,100); // measured in parts per million (ppm)
CREATE_CHAR(uint8_t,CarbonMonoxideDetected,0,0,1,NORMAL,ABNORMAL); // indicates if abnormal level is detected
CREATE_CHAR(double,CarbonDioxideLevel,0,0,100000); // measured on parts per million (ppm)
CREATE_CHAR(double,CarbonDioxidePeakLevel,0,0,100000); // measured in parts per million (ppm)
CREATE_CHAR(uint8_t,CarbonDioxideDetected,0,0,1,NORMAL,ABNORMAL); // indicates if abnormal level is detected
CREATE_CHAR(uint8_t,ChargingState,0,0,2,NOT_CHARGING,CHARGING,NOT_CHARGEABLE); // indicates state of battery charging
CREATE_CHAR(uint8_t,ClosedCaptions,0,0,1); // unused by any Service
CREATE_CHAR(double,CoolingThresholdTemperature,10,10,35); // cooling turns on when temperature (in Celsius) rises above this threshold
CREATE_CHAR(uint32_t,ColorTemperature,200,140,500); // measured in inverse megaKelvin (= 1,000,000 / Kelvin)
CREATE_CHAR(uint8_t,ContactSensorState,1,0,1,DETECTED,NOT_DETECTED); // indictates if contact is detected (i.e. closed)
CREATE_CHAR(const char *,ConfiguredName,"unnamed",0,1); // a "configurable" Service name - any updates made from within the Home App trigger an update in HomeSpan and vice versa.
CREATE_CHAR(double,CurrentAmbientLightLevel,1,0.0001,100000); // measured in Lux (lumens/m<sup>2</sup>
CREATE_CHAR(int,CurrentHorizontalTiltAngle,0,-90,90); // current angle (in degrees) of slats from fully up (-90) to fully open (0) to fully down (90)
CREATE_CHAR(uint8_t,CurrentAirPurifierState,1,0,2,INACTIVE,IDLE,PURIFYING); // indicates current state of air purification
CREATE_CHAR(uint8_t,CurrentSlatState,0,0,2,FIXED,JAMMED,SWINGING); // indicates current state of slats
CREATE_CHAR(uint8_t,CurrentPosition,0,0,100); // current position (as a percentage) from fully closed (0) to full open (100)
CREATE_CHAR(int,CurrentVerticalTiltAngle,0,-90,90); // current angle (in degrees) of slats from fully left (-90) to fully open (0) to fully right (90)
CREATE_CHAR(uint8_t,CurrentVisibilityState,0,0,1,VISIBLE,NOT_VISIBLE); // current visibility of the Service, as selectable on the Settings Page of the Home App
CREATE_CHAR(uint8_t,CurrentHumidifierDehumidifierState,1,0,3,INACTIVE,IDLE,HUMIDIFYING,DEHUMIDIFYING); // indicates current state of humidifier/dehumidifer
CREATE_CHAR(uint8_t,CurrentDoorState,1,0,4,OPEN,CLOSED,OPENING,CLOSING,STOPPED); // indicates current state of a door
CREATE_CHAR(uint8_t,CurrentFanState,1,0,2,INACTIVE,IDLE,BLOWING); // indicates current state of a fan
CREATE_CHAR(uint8_t,CurrentHeatingCoolingState,0,0,2,IDLE,HEATING,COOLING); // indicates whether appliance is currently heating, cooling, or just idle
CREATE_CHAR(uint8_t,CurrentHeaterCoolerState,1,0,3,INACTIVE,IDLE,HEATING,COOLING); // indicates whether appliance is currently heating, cooling, idle, or off
CREATE_CHAR(uint8_t,CurrentMediaState,0,0,5); // not used
CREATE_CHAR(double,CurrentRelativeHumidity,0,0,100); // current humidity measured as a percentage
CREATE_CHAR(double,CurrentTemperature,0,0,100); // current temperature measured in Celsius
CREATE_CHAR(int,CurrentTiltAngle,0,-90,90); // current angle (in degrees) of slats from fully up or left (-90) to fully open (0) to fully down or right (90)
CREATE_CHAR(double,FilterLifeLevel,0,0,100); // measures as a percentage of remaining life
CREATE_CHAR(uint8_t,FilterChangeIndication,0,0,1,NO_CHANGE_NEEDED,CHANGE_NEEDED); // indicates state of filter
CREATE_CHAR(const char *,FirmwareRevision,"1.0.0",0,1); // must be in form x[.y[.z]] - informational only
CREATE_CHAR(const char *,HardwareRevision,"1.0.0",0,1); // must be in form x[.y[.z]] - informational only
CREATE_CHAR(double,HeatingThresholdTemperature,16,0,25); // heating turns on when temperature (in Celsius) falls below this threshold
CREATE_CHAR(boolean,HoldPosition,false,0,1); // deprecated
CREATE_CHAR(double,Hue,0,0,360); // color (in degrees) from red (0) to green (120) to blue (240) and back to red (360)
CREATE_CHAR(boolean,Identify,1,1,1,RUN_ID=1); // triggers an update when HomeKit wants HomeSpan to run its identification routine for an Accessory
CREATE_CHAR(uint32_t,Identifier,0,0,255); // numerical Identifer of the <b>InputSource</b>.
CREATE_CHAR(uint8_t,InputDeviceType,0,0,6); // not used
CREATE_CHAR(uint8_t,InputSourceType,0,0,10); // not used
CREATE_CHAR(uint8_t,InUse,0,0,1,NOT_IN_USE,IN_USE); // if Service is set to active, this indictes whether it is currently in use
CREATE_CHAR(uint8_t,IsConfigured,0,0,1,NOT_CONFIGURED,CONFIGURED); // indicates if a predefined Service has been configured
CREATE_CHAR(uint8_t,LeakDetected,0,0,1,NOT_DETECTED,DETECTED); // indictates if a leak is detected
CREATE_CHAR(uint8_t,LockCurrentState,0,0,3,UNLOCKED,LOCKED,JAMMED,UNKNOWN); // indicates state of a lock
CREATE_CHAR(uint8_t,LockPhysicalControls,0,0,1,CONTROL_LOCK_DISABLED,CONTROL_LOCK_ENABLED); // indicates if local control lock is enabled
CREATE_CHAR(uint8_t,LockTargetState,0,0,1,UNLOCK,LOCK); // indicates desired state of lock
CREATE_CHAR(const char *,Manufacturer,"HomeSpan",0,1); // any string - informational only
CREATE_CHAR(const char *,Model,"HomeSpan-ESP32",0,1); // any string - informational only
CREATE_CHAR(boolean,MotionDetected,0,0,1,NOT_DETECTED,DETECTED); // indicates if motion is detected
CREATE_CHAR(boolean,Mute,0,0,1,OFF,ON); // not used
CREATE_CHAR(const char *,Name,"unnamed",0,1); // default name of a Service used <i>only</i> during initial pairing
CREATE_CHAR(double,NitrogenDioxideDensity,0,0,1000); // measured in &micro;g/m<sup>3</sup>
CREATE_CHAR(boolean,ObstructionDetected,0,0,1,NOT_DETECTED,DETECTED); // indicates if obstruction is detected
CREATE_CHAR(double,PM25Density,0,0,1000); // 2.5-micron particulate density, measured in &micro;g/m<sup>3</sup>
CREATE_CHAR(uint8_t,OccupancyDetected,0,0,1,NOT_DETECTED,DETECTED); // indicates if occupanccy is detected
CREATE_CHAR(boolean,OutletInUse,0,0,1,NOT_IN_USE,IN_USE); // indicates if an appliance or light is plugged into the outlet, regardless of whether on or off
CREATE_CHAR(boolean,On,0,0,1,OFF,ON); // indicates if the Service is active/on
CREATE_CHAR(double,OzoneDensity,0,0,1000); // measured in &micro;g/m<sup>3</sup>
CREATE_CHAR(uint8_t,PictureMode,0,0,13); // not used
CREATE_CHAR(double,PM10Density,0,0,1000); // 10-micron particulate density, measured in &micro;g/m<sup>3</sup>
CREATE_CHAR(uint8_t,PositionState,2,0,2,GOING_TO_MINIMUM,GOING_TO_MAXIMUM,STOPPED); // deprecated
CREATE_CHAR(uint8_t,PowerModeSelection,0,0,0,VIEW_SETTINGS); // when defined, creates a "View TV Settings" button in the Home App that triggers an update to this Characteristic when pressed
CREATE_CHAR(uint8_t,ProgramMode,0,0,2,NONE,SCHEDULED,SCHEDULE_OVERRIDEN); // indicates if pre-scheduled program is running
CREATE_CHAR(uint8_t,ProgrammableSwitchEvent,0,0,2,SINGLE_PRESS,DOUBLE_PRESS,LONG_PRESS); // specifies type of button press
CREATE_CHAR(double,RelativeHumidityDehumidifierThreshold,50,0,100); // dehumidfier turns on when humidity rises above this threshold
CREATE_CHAR(double,RelativeHumidityHumidifierThreshold,50,0,100); // humidfier turns on when humidity falls below this threshold
CREATE_CHAR(uint32_t,RemainingDuration,60,0,3600); // duration (in seconds) remaining for Service to be active/on
CREATE_CHAR(uint8_t,RemoteKey,4,4,15,UP=4,DOWN,LEFT,RIGHT,CENTER,BACK,PLAY_PAUSE=11,INFO=15); // triggers an update when the corresponding key is pressed in the Remote Control widget on an iPhone
CREATE_CHAR(uint8_t,ResetFilterIndication,1,1,1,RESET_FILTER=1); // triggers and update when the user chooses to reset the <b>FilterChangeIndication</b> from the Home App
CREATE_CHAR(int,RotationDirection,0,0,1,CLOCKWISE,COUNTERCLOCKWISE); // indicates the rotation direction of a fan
CREATE_CHAR(double,RotationSpeed,0,0,100); // measured as a percentage
CREATE_CHAR(double,Saturation,0,0,100); // color saturation, measured as a percentage
CREATE_CHAR(uint8_t,SecuritySystemAlarmType,0,0,1,KNOWN,UNKNOWN); // indicates whether alarm was triggered for known reason
CREATE_CHAR(uint8_t,SecuritySystemCurrentState,3,0,4,ARMED_STAY,ARMED_AWAY,ARMED_NIGHT,DISARMED,ALARM_TRIGGERED); // indicates current state of the security system
CREATE_CHAR(uint8_t,SecuritySystemTargetState,3,0,3,ARM_STAY,ARM_AWAY,ARM_NIGHT,DISARM); // indicates desired state of the security system
CREATE_CHAR(const char *,SerialNumber,"HS-12345",0,1); // any string - informational only
CREATE_CHAR(uint8_t,ServiceLabelIndex,1,1,255); // numerical index used to distinguish multiple copies of the same Service within an Accessory
CREATE_CHAR(uint8_t,ServiceLabelNamespace,1,0,1,DOTS,NUMERALS); // unused
CREATE_CHAR(uint8_t,SlatType,0,0,1,HORIZONTAL,VERTICAL); // indicates the direction of a slat or group of slats
CREATE_CHAR(uint8_t,SleepDiscoveryMode,0,0,1); // not used
CREATE_CHAR(uint8_t,SmokeDetected,0,0,1,NOT_DETECTED,DETECTED); // indicates if smoke is detected
CREATE_CHAR(boolean,StatusActive,1,0,1,NOT_FUNCTIONING,FUNCTIONING); // indicates whether the Service is properly functioning
CREATE_CHAR(uint8_t,StatusFault,0,0,1,NO_FAULT,FAULT); // indicates whether the Service has a fault
CREATE_CHAR(uint8_t,StatusJammed,0,0,1,NOT_JAMMED,JAMMED); // indicates whether the Service has been "jammed"
CREATE_CHAR(uint8_t,StatusLowBattery,0,0,1,NOT_LOW_BATTERY,LOW_BATTERY); // indicates state of battery
CREATE_CHAR(uint8_t,StatusTampered,0,0,1,NOT_TAMPERED,TAMPERED); // indicates whether the Service has been tampered with
CREATE_CHAR(double,SulphurDioxideDensity,0,0,1000); // measured in &micro;g/m<sup>3</sup>
CREATE_CHAR(uint8_t,SwingMode,0,0,1,SWING_DISABLED,SWING_ENABLED); // indicates whether swing-nmode is enabled
CREATE_CHAR(uint8_t,TargetAirPurifierState,1,0,1,MANUAL,AUTO); // indicates desired state of air purifier
CREATE_CHAR(uint8_t,TargetFanState,1,0,1,MANUAL,AUTO); // indicates desired state of fan
CREATE_CHAR(int,TargetTiltAngle,0,-90,90); // indicated desired angle (in degrees) of slats from fully up or left (-90) to fully open (0) to fully down or right (90)
CREATE_CHAR(uint8_t,TargetHeaterCoolerState,0,0,2,AUTO,HEAT,COOL); // indicates desired state of heater/cooler
CREATE_CHAR(uint32_t,SetDuration,60,0,3600); // specifies the duration (in seconds) for a Service to remain on once activated
CREATE_CHAR(int,TargetHorizontalTiltAngle,0,-90,90); // indicates desired angle (in degrees) of slats from fully up (-90) to fully open (0) to fully down (90)
CREATE_CHAR(uint8_t,TargetHumidifierDehumidifierState,0,0,2,AUTO,HUMIDIFY,DEHUMIDIFY); // indicates desired state of humidifier/dehumidifier
CREATE_CHAR(uint8_t,TargetPosition,0,0,100); // indicates target position (as a percentage) from fully closed (0) to full open (100)
CREATE_CHAR(uint8_t,TargetDoorState,1,0,1,OPEN,CLOSED); // indicates desired state of door
CREATE_CHAR(uint8_t,TargetHeatingCoolingState,0,0,3,OFF,HEAT,COOL,AUTO); // indicates desired state of appliance
CREATE_CHAR(uint8_t,TargetMediaState,0,0,2); // unused
CREATE_CHAR(double,TargetRelativeHumidity,0,0,100); // indicates desired humidity measured as a percentage
CREATE_CHAR(double,TargetTemperature,16,10,38); // indicates desired temperature measures in Celsius
CREATE_CHAR(uint8_t,TargetVisibilityState,0,0,1,VISIBLE,NOT_VISIBLE); // indicates desired visibility of the Service, as selectable on the Settings Page of the Home App
CREATE_CHAR(uint8_t,TemperatureDisplayUnits,0,0,1,CELSIUS,FAHRENHEIT); // indicates the desired units to display the temperature on the device itself (has no effect on Home App)
CREATE_CHAR(int,TargetVerticalTiltAngle,0,-90,90); // indicates desired angle (in degrees) of slats from fully left (-90) to fully open (0) to fully right (90)
CREATE_CHAR(uint8_t,ValveType,0,0,3,GENERIC,IRRIGATION,SHOWER_HEAD,FAUCET); // indicates the type of valve
CREATE_CHAR(const char *,Version,"1.0.0",0,1); // unused
CREATE_CHAR(double,VOCDensity,0,0,1000); // measured in &micro;g/m<sup>3</sup>
CREATE_CHAR(uint8_t,Volume,0,0,100); // unused
CREATE_CHAR(uint8_t,VolumeControlType,3,0,3,NONE,RELATIVE,RELATIVE_CURRENT,ABSOLUTE); // indicates the type of volume control
CREATE_CHAR(uint8_t,VolumeSelector,0,0,1,VOLUME_UP,VOLUME_DOWN); // triggered by presses to the iPhone's volume up/down buttons when TV is selected in the Remote Control widget
CREATE_CHAR(double,WaterLevel,0,0,100); // measured as a percentage
}

View File

@ -27,40 +27,69 @@
#include "HomeSpan.h"
#define MAX_LIGHTS 2
void setup() {
Serial.begin(115200);
homeSpan.setLogLevel(1).setStatusPin(13);
pinMode(21,OUTPUT);
homeSpan.setControlPin(21,SpanToggle::TRIGGER_ON_HIGH );
homeSpan.setControlPin(21,PushButton::TRIGGER_ON_HIGH );
homeSpan.enableWebLog(50,"pool.ntp.org","UTC");
homeSpan.setLogLevel(2);
homeSpan.begin(Category::Lighting,"HomeSpan Max");
homeSpan.begin(Category::Lighting,"HomeSpan Test");
new SpanAccessory(); // start with Bridge Accessory
new Service::AccessoryInformation();
new Characteristic::Identify();
// First dual-light/dual-switch Accessory
new SpanAccessory();
new Service::AccessoryInformation();
new Characteristic::Identify();
new Characteristic::Name("Access-1"); // the AccessoryInformation Service seems to require Name(), and will ignore ConfiguredName()
for(int i=0;i<MAX_LIGHTS;i++){
new SpanAccessory();
new Service::AccessoryInformation();
new Characteristic::Identify();
char c[100];
sprintf(c,"Light-%d",i);
new Characteristic::Name(c);
new Service::LightBulb();
new Characteristic::On(0,true);
new Characteristic::Saturation(0,true);
WEBLOG("Configuring %s\n",c);
}
new Characteristic::On(0);
new Characteristic::ConfiguredName("Main Light"); // here we use ConfiguredName() instead of Name(). This is properly reflected in Home App during pairing
new Service::LightBulb();
new Characteristic::On(0);
new Characteristic::ConfiguredName("Night Light");
new Service::Switch();
new Characteristic::On(0);
new Characteristic::ConfiguredName("Switch-A");
new Service::Switch();
new Characteristic::On(0);
new Characteristic::ConfiguredName("Switch-B");
// Second dual-light/dual-switch Accessory
new SpanAccessory();
new Service::AccessoryInformation();
new Characteristic::Identify();
new Characteristic::Name("Access-2"); // note as above we use Name() instead of ConfiguredName() for the AccessoryInformation Service
new Service::LightBulb();
new Characteristic::On(0);
new Characteristic::ConfiguredName("Aux Light");
new Service::LightBulb();
new Characteristic::On(0);
new Characteristic::ConfiguredName("Night Light");
new Service::Switch();
new Characteristic::On(0);
new Characteristic::ConfiguredName("Switch-A");
new Service::Switch();
new Characteristic::On(0);
new Characteristic::ConfiguredName("Switch-B");
Characteristic::AirQuality *air = new Characteristic::AirQuality;
air->setVal(Characteristic::AirQuality::GOOD);
air->setVal(air->GOOD);
new SpanUserCommand('w', " - get web log test",webLogTest); // simulate getting an HTTPS request for weblog
// homeSpan.autoPoll(8192+10000);
}
//////////////////////////////////////
@ -70,17 +99,3 @@ void loop(){
homeSpan.poll();
}
//////////////////////////////////////
void webLogTest(const char *dummy){
Serial.printf("\n*** In Web Log Test. Starting Custom Web Log Handler\n"); // here is where you would perform any HTTPS initializations
homeSpan.getWebLog(webLogHandler);
}
void webLogHandler(const char *buf){
if(buf!=NULL)
Serial.printf("%s",buf); // here is where you would transmit data to the HTTPS connection
else
Serial.print("*** DONE!\n\n"); // here is where you would close the HTTPS connection
}

5
tools/makeServiceList Executable file
View File

@ -0,0 +1,5 @@
#!/bin/zsh
grep -B 1000 "AUTOGENERATED_TEXT" ../docs/ServiceList.md > ServiceList.md
./makeServices ../src/Characteristics.h ../src/Span.h >> ServiceList.md
mv ServiceList.md ../docs/ServiceList.md

102
tools/makeServices Executable file
View File

@ -0,0 +1,102 @@
#!/usr/bin/awk -f
BEGIN {
ws="[ \t,();]+" # regexp of separators
ltws="^" ws "|" ws "$" # regexp of leading and trailing separators
nServs=0 # number of Services found
}
{
split($0,line,"//") # separate line into program and (optional) comment
gsub(ltws,"",line[1]) # strip out leading or trailing separators
gsub("[ \t]+","",line[1]) # strip out any other spaces
n=split(line[1],x,ws) # split program portion according to separators
if(x[1]=="CREATE_SERV"){
currentService=x[2]
services[nServs++]=currentService
uuid[currentService]=x[3]
desc[currentService]=line[2] # save optional comment as description of Service
nChars[currentService]=0
}
else if(x[1]=="REQ" || x[1]=="OPT"){
servChars[currentService,nChars[currentService]]=x[2]
servReq[currentService,nChars[currentService]]=(x[1]=="REQ")
nChars[currentService]++
}
else if(x[1]=="CREATE_CHAR"){
char=x[3]
default[char]=x[4]
min[char]=x[5]
max[char]=x[6]
nConstants[char]=n-6 # parse any pre-defined constants
value=0 # default starting value of constants
for(i=0;i<nConstants[char];i++){
v=split(x[i+7],y,"=") # split name of constant from (optional) value
constantName[char,i]=y[1]
if(v==2) # override value if provided
value=y[2]
constantValue[char,i]=value
if(index(perms[char],"PR") && x[4]==value)
defaultMark[char,i]=":heavy_check_mark:"
value++
}
notes[char]=line[2] # save optional comment as notes for Characteristic
}
else if(x[1]=="HAPCHAR"){
char=x[2]
uuid[char]=x[3]
perms[char]=x[4]
format[char]=tolower(x[5])
static[char]=x[6]
}
}
END {
printf("\n\n");
for(i=0;i<nServs;i++){
s=services[i]
printf("## %s (%s)\n",s,uuid[s])
printf("<details><summary>%s</summary><br><table>\n",desc[s])
printf("<tr><th>Characteristic</th><th>Format</th><th>Perms</th><th>Min</th><th>Max</th><th>Constants/Defaults</th></tr>\n")
for(j=0;j<nChars[s];j++){
char=servChars[s,j]
printf("<tr>")
printf("<td><b>%s (%s) %s</b><ul><li>%s</li></ul></td>",char,uuid[char],servReq[s,j]?":small_blue_diamond:":"",notes[char])
printf("<td align=\"center\">%s</td>",format[char])
printf("<td align=\"center\">%s</td>",perms[char])
if(format[char]!="string")
printf("<td align=\"center\">%s</td><td align=\"center\">%s</td>",min[char],max[char])
else
printf("<td align=\"center\">-</td><td align=\"center\">-</td>")
if(nConstants[char]>0){
printf("<td><ul>")
for(k=0;k<nConstants[char];k++)
printf("<li><b>%s&nbsp(%d)&nbsp;</b>%s</li>",constantName[char,k],constantValue[char,k],defaultMark[char,k])
printf("</ul></td>")
} else {
printf("<td align=\"center\">%s</td>",default[char])
}
printf("</tr>\n")
}
printf("</table></details>\n\n")
}
printf("---\n\n")
printf("[↩️](../README.md) Back to the Welcome page\n\n")
}