# Philips Air Purifier Binding
This binding monitors and controls Philips air purifiers and combined air purifier/humidifiers over the local network. No cloud account is needed.
The binding builds on the protocol reverse engineering done by rgerganov (opens new window) in py-air-control (opens new window), many thanks for that work.
# Supported Things
Philips air purifiers use one of two local protocols, depending on their age:
- HTTP: older models, discovered using UPnP. The communication is encrypted with a key that the binding exchanges with the device automatically.
- CoAP: models released from about 2019 on. These devices push their state changes to openHAB.
Some models, such as the AC2889 and AC3829, used HTTP with early firmware and use CoAP after a firmware update.
Use the coap thing type for a device with updated firmware, and the thing type of the model (or universal) for a device with HTTP firmware.
| Thing Type | Protocol | Description |
|---|---|---|
| ac2889-10 | HTTP | Philips Air Purifier AC2889/10 |
| ac2729 | HTTP | Philips Air Purifier/Humidifier AC2729 |
| ac1214-10 | HTTP | Philips Air Purifier AC1214/10 |
| ac3829-10 | HTTP | Philips Air Purifier/Humidifier AC3829/10 |
| universal | HTTP | Any other Philips air purifier using the HTTP protocol |
| coap | CoAP | Philips air purifiers using the CoAP protocol |
The following models have been tested: AC1214/10, AC2729, AC2729/50, AC2889/10, AC2939/10, AC3033/10, AC3829/10 and AC5659/10. Other models using the same protocols are likely to work as well; feedback on compatibility with other models is welcome.
# Recent CoAP Models
CoAP devices such as the AC2889, AC3033, AC3829 and AC4236 series (the AC2889 and AC3829 only with updated firmware, see above) report their state with the classic field names (e.g. pwr, om, pm25) and are fully supported.
Recent models report their state with numbered field names instead: newer models use names like D03102, older ones names like D03-02.
Examples are the AC0850, AC0950, AC1715, AC2210, AC3210, AC3420, AC3737, AMF and HU series.
Their modes, fan speeds and other settings are encoded differently per model, so the binding uses a device profile per model to translate them.
# Device Profiles
The profile is detected from the model that the device reports and is shown in the thing property deviceProfile, see Thing Properties.
When the model of your device is not detected, you can select the profile of a model that is the same or similar in the advanced thing configuration parameter deviceProfile.
The device then is controlled like that model, without the binding needing an update.
Select basic again if the device does not behave as expected.
Profile (deviceProfile) | Models | Field names |
|---|---|---|
auto | Detects the profile | |
basic | Other recent models: sensors, power and child lock | both |
unicorn | AC2210, AC2220, AC2221, AC3210, AC3220, AC3221, AC4220, AC4221 | D03102 |
ac0950 | AC0950, AC0951 | D03102 |
ac3737 | AC3737 | D03102 |
ac2939 | AC2939 and other models of the MarsLE range | classic |
ac1715 | AC1715 | D03-02 |
ac0850 | AC0850 (with the AWS_Philips_AIR Wi-Fi firmware) | D03-02 |
A profile only applies to a device with the field names it is for, otherwise the profile is detected.
| Channel | basic | unicorn | ac0950 | ac3737 | ac1715, ac0850 |
|---|---|---|---|---|---|
power | read and write | read and write | read and write | read and write | read and write |
child-lock | read and write1 | read and write | read and write | read and write | read and write |
pm25, allergen-index | read only | read only | read only | read only | read only |
error-code | read only | read only | read only | read only | read only |
humidity, temperature | read only | read only | not reported | read only | read only |
tvoc | read only | read only | read only | read only | read only |
air-quality-threshold, displayed-index | read only | read and write | read and write | read and write | read and write |
mode | not supported | P (auto), S (sleep) | P, S, GT, T | P, S | P, S |
fan-speed | not supported | 1 to 5, m (medium), t (turbo) | read only | 1, 2, t | 1, 2, t (t only: ac0850) |
timer | not supported | 0 (off) to 12 hours | 0 (off) to 12 hours | not supported | not supported |
timer-remaining | read only2 | read only | read only | read only | not supported |
target-humidity | read only2 | read and write | not supported | read and write | not supported |
beep, standby-sensors | not supported | read and write | read and write | not supported | not supported |
display, lamp-mode | not supported | read and write | not supported | not supported | not supported |
display-brightness | not supported | 0 (off), 101 (auto), 115 (low), 123 (bright) | 0, 115, 123 | 0, 50, 100 | not supported |
allergy-sleep | not supported | read and write | not supported | read and write | not supported |
pre-filter-life, hepa-filter-life | read only | read only | read only | read only | read only |
| all other channels | not supported, they stay NULL | not supported | not supported | not supported | not supported |
- 1 With the older field names (
D03-xx) thebasicprofile only reads the child lock; theac1715andac0850profiles also set it. - 2 Only the newer field names (
D03xxx).
Notes on the profiles:
- The mode is
M(manual) while a fan speed is selected, and the fan speed shows the speed the device chose in auto and sleep mode (Unicorn). Selecting a fan speed switches the device to manual mode; there is no separate command for the manual mode. For theac3737,ac1715andac0850profiles selecting a mode or fan speed also switches the device on. - The
ac2939profile is for a model with the classic field names, so all channels of the classic models apply. ItsmodeisAG(auto),GT(gentle),S(sleep) orT(turbo). The device selects the fan speed for the mode itself, sofan-speedshows the speed and has no manual mode to set it. - The
ac0950profile is theunicornprofile for the small models of that range. Like in the Philips app, these models have the modesP(auto),S(sleep),GT(gentle) andT(turbo) inmode. The device selects the fan speed for the mode itself, sofan-speedonly shows it:1in auto and sleep mode,2in gentle mode andtin turbo mode. These models do not reporthumidityandtemperatureand have notarget-humidity,allergy-sleep,displayandlamp-mode. Theirdisplay-brightnessis0(off),115(low) or123(bright). - The timer,
target-humidityand the settings channels (beep,standby-sensors,allergy-sleep,display,display-brightnessandlamp-mode) are added once the device reports them. Thedisplayswitch is on while the display is on. - Commands are only sent for the values listed in the table. Other values are ignored.
- The
display-brightnessvalues101,115and123are the codes the device uses, not percentages.
The profiles follow the Philips Air+ app and the philips-airpurifier-coap (opens new window) integration. Reading the status of an AC3210/12, an AC0950/10 and an AC2939/10 has been confirmed on a real device; the commands have not been confirmed on a device yet, and neither has any other recent model. Feedback is welcome.
The thing properties modelId, firmwareVersion and name are set for these models as well.
If such a device is not discovered, add it manually as coap thing with its IP address.
# Helping to Support a New Model
Adding full support for a model requires knowing which field holds which setting and which values it takes. If you own a model that is not fully supported, you can help by collecting this information:
Add the device as
coapthing (oruniversalthing for an HTTP device) and make sure it is online.Enable debug logging for the binding in the openHAB console:
log:set DEBUG org.openhab.binding.philipsairChange one setting at a time with the buttons on the device or in the Philips app, and note what you changed, e.g. "mode from Auto to Sleep" or "fan speed from 1 to 2". Wait until a new status line appears in
openhab.logafter each change:Status from <ip>: {...}for CoAP devices,Philips Air Purifier device response: '{...}'for HTTP devices. Go through all modes, fan speeds, light levels, the timer, the child lock and, for humidifiers, the humidity setpoint.Note the values the Philips app shows at the same time, e.g. PM2.5, humidity, temperature and the remaining filter lifetimes.
Reset the log level with
log:set INFO org.openhab.binding.philipsair.
Then open an issue on GitHub (opens new window) or a topic on the openHAB community forum (opens new window), and include:
- the model number printed on the device label (e.g.
AC3737/10) and its firmware version - the status log lines, each with the change you made just before it
- the values shown in the Philips app
The status lines do not contain passwords or keys, but they do contain the device name and ID; you may replace those before posting.
# Discovery
The binding discovers Philips air purifiers on the local network automatically.
HTTP devices are found using UPnP: the models listed above are discovered as their own thing type, all other HTTP devices as universal thing.
CoAP devices are found with a CoAP broadcast and discovered as coap thing.
Background discovery is enabled by default.
It can be disabled in the UI under Settings → Add-on Settings → Philips Air Purifier Binding, or by adding the following line to services/runtime.cfg:
discovery.philipsair:background=false
This setting applies to both the UPnP and the CoAP discovery. With background discovery disabled, HTTP devices (UPnP) are not reported by a manual scan either, while CoAP devices are still found by a manual scan.
# Thing Configuration
Discovered things do not need any configuration.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| host | text | yes | IP address or hostname of the device. Set automatically upon discovery. | |
| key | text | no | HTTP devices only: encryption key. Exchanged with the device automatically when empty. | |
| deviceUUID | text | no | Device ID. Set automatically upon discovery and used to identify discovered things. | |
| refreshInterval | integer | no | 60 | Refresh interval in seconds (minimum 5). For CoAP devices the interval at which the connection is checked. |
| deviceProfile | text | no | auto | CoAP devices only (advanced): the model profile, see Device Profiles. Detected when auto. |
| humidityOffset | decimal | no | 0 | Offset in % added to the humidity readings (-100 to 100). |
| temperatureOffset | decimal | no | 0 | Offset in °C added to the temperature readings (-50 to 50). |
HTTP devices are polled at the refresh interval. When the device rejects the key, for example after a reset, the binding exchanges a new key automatically.
CoAP devices push their state changes, so they are not polled. For these devices the refresh interval is only used to check the connection. When no update has arrived for the refresh interval (at least 30 seconds), the binding checks whether the device still answers. A device that sends no updates, for example in standby, stays online as long as it answers this check. The thing goes offline when the device neither sends an update nor answers within twice the refresh interval (at least 60 seconds).
# Channels
The channels are organized in the groups controls, controls-ui, sensors and filters.
| Channel Group | Channel ID | Item Type | Read/Write | Description |
|---|---|---|---|---|
| controls | power | Switch | RW | Device power |
| controls | fan-speed | String | RW | Fan speed: s (silent), 1, 2, 3, t (turbo). Setting the fan speed also switches the device to manual mode. |
| controls | mode | String | RW | Mode: P (auto), A (allergen), S (sleep), M (manual), B (bacteria), N (night) |
| controls | timer | Number | RW | Switch-off timer in hours (0 is off, up to 5 or 12 depending on the model) |
| controls | timer-remaining | Number:Time | R | Time left until the timer switches the device off |
| controls | child-lock | Switch | RW | Child lock |
| controls | target-humidity | Number:Dimensionless | RW | Humidity setpoint (40-70 %, in steps of 10 %) |
| controls | function | String | RW | Function: P (purification), PH (purification and humidification) |
| controls-ui | button-light | Switch | RW | Button light |
| controls-ui | light-level | Number:Dimensionless | RW | Display light level (0, 25, 50, 75, 100 %) |
| controls | standby-sensors | Switch | RW | The sensors keep measuring in standby (advanced) |
| controls | allergy-sleep | Switch | RW | Sleep mode that is gentle for allergic people (advanced) |
| controls-ui | displayed-index | String | RW | Index shown on the display: 0 (allergen index), 1 (PM2.5), 2 (gas, only offered on models with a gas sensor) |
| controls-ui | display-brightness | String | RW | Brightness of the display, with the steps of the model (see the device profiles) |
| controls-ui | display | Switch | RW | The display is on (advanced) |
| controls-ui | lamp-mode | String | RW | What the lamp shows: 0 (off), 1 (air quality), 2 (ambient) |
| controls-ui | beep | Switch | RW | The device beeps when a button is pressed (advanced) |
| sensors | pm25 | Number:Density | R | PM2.5 particle concentration |
| sensors | allergen-index | Number | R | Allergen index |
| sensors | air-quality-threshold | Number | RW | Air quality level at which the Philips app sends a notification: 1 (good), 4 (fair), 7 (poor), 10 (very poor); on the AC4373 and AC4375 13, 19, 29, 40 |
| sensors | error-code | String | R | Error code, e.g. 0 (no error), 49408 (no water), 32768 (water tank open), 49155 (clean pre-filter) |
| sensors | humidity | Number:Dimensionless | R | Current humidity, corrected by humidityOffset |
| sensors | temperature | Number:Temperature | R | Current temperature, corrected by temperatureOffset |
| sensors | water-level | Number:Dimensionless | R | Water tank level |
| sensors | tvoc | Number | R | TVOC level; recent models report it as an index from 1 to 4 |
| sensors | rssi | Number:Power | R | Wi-Fi signal strength (advanced) |
| filters | pre-filter-life | Number:Time | R | Time until the pre-filter needs to be cleaned |
| filters | hepa-filter-life | Number:Time | R | Remaining lifetime of the HEPA filter |
| filters | carbon-filter-life | Number:Time | R | Remaining lifetime of the active carbon filter |
| filters | wick-filter-life | Number:Time | R | Remaining lifetime of the humidifier wick |
The channels target-humidity, function, humidity, temperature, water-level and wick-filter-life are only available on models with a humidifier or the corresponding sensors.
The channels timer and timer-remaining are only available on models with a switch-off timer.
The ac2729 and ac3829-10 thing types always have these channels.
For the other thing types, in particular universal and coap, they are added automatically once the device reports the corresponding value.
The channels tvoc and rssi are added the same way on all thing types, as only some models report them.
The channels beep, display, display-brightness, lamp-mode, standby-sensors and allergy-sleep are added the same way, for the CoAP devices that have these settings.
# Thing Properties
| Property | Description |
|---|---|
| vendor | Always Philips |
| modelId | Model reported by the device, e.g. AC2889/10 |
| firmwareVersion | Firmware version of the device |
| name | Name of the device as configured in the Philips app |
| deviceType | Device type reported during discovery |
| manufacturer | Manufacturer reported during discovery |
| macAddress | MAC address of the device, reported during UPnP discovery |
| preFilterType | Type code of the pre-filter, if reported by the device |
| hepaFilterType | Type code of the HEPA filter, e.g. A3, if reported by the device |
| carbonFilterType | Type code of the active carbon filter, e.g. C7, if reported by the device |
| deviceProfile | Name of the device profile resolved for a CoAP device, e.g. UNICORN or CLASSIC |
| deviceProfileHost | Host the deviceProfile was resolved for |
The properties deviceType, manufacturer and macAddress are only set on discovered things.
The properties deviceProfile and deviceProfileHost are stored for every CoAP device once it has reported its status.
After a restart, the stored profile is used until the device reports its status, as long as the configured host is still the host in deviceProfileHost.
# Full Example
# Thing Configuration
Thing philipsair:ac2889-10:livingroom "Air Purifier Living Room" @ "Living Room" [ host="192.168.1.10", refreshInterval=15 ]
Thing philipsair:ac3829-10:bedroom "Air Purifier Bedroom" @ "Bedroom" [ host="192.168.1.11", refreshInterval=15 ]
Thing philipsair:coap:office "Air Purifier Office" @ "Office" [ host="192.168.1.12" ]
# Item Configuration
Switch LivingRoom_AP_Power "Power" <switch> { channel="philipsair:ac2889-10:livingroom:controls#power" }
String LivingRoom_AP_FanSpeed "Fan Speed" <fan> { channel="philipsair:ac2889-10:livingroom:controls#fan-speed" }
String LivingRoom_AP_Mode "Mode" <text> { channel="philipsair:ac2889-10:livingroom:controls#mode" }
Number LivingRoom_AP_Timer "Timer [%d h]" <time> { channel="philipsair:ac2889-10:livingroom:controls#timer" }
Number:Time LivingRoom_AP_TimerLeft "Timer Remaining" <time> { channel="philipsair:ac2889-10:livingroom:controls#timer-remaining" }
Switch LivingRoom_AP_ButtonLight "Button Light" <lightbulb> { channel="philipsair:ac2889-10:livingroom:controls-ui#button-light" }
Number:Dimensionless LivingRoom_AP_LightLevel "Light Level" <lightbulb> { channel="philipsair:ac2889-10:livingroom:controls-ui#light-level" }
String LivingRoom_AP_Index "Displayed Index" <text> { channel="philipsair:ac2889-10:livingroom:controls-ui#displayed-index" }
Number:Density LivingRoom_AP_PM25 "PM2.5" <smoke> { channel="philipsair:ac2889-10:livingroom:sensors#pm25" }
Number LivingRoom_AP_Allergen "Allergen Index" <text> { channel="philipsair:ac2889-10:livingroom:sensors#allergen-index" }
String LivingRoom_AP_Error "Error" <error> { channel="philipsair:ac2889-10:livingroom:sensors#error-code" }
Number:Time LivingRoom_AP_PreFilter "Pre-filter" <text> { channel="philipsair:ac2889-10:livingroom:filters#pre-filter-life" }
Number:Time LivingRoom_AP_HepaFilter "HEPA Filter" <text> { channel="philipsair:ac2889-10:livingroom:filters#hepa-filter-life" }
Number:Time LivingRoom_AP_CarbonFilter "Carbon Filter" <text> { channel="philipsair:ac2889-10:livingroom:filters#carbon-filter-life" }
Switch Bedroom_AP_Power "Power" <switch> { channel="philipsair:ac3829-10:bedroom:controls#power" }
Switch Bedroom_AP_ChildLock "Child Lock" <lock> { channel="philipsair:ac3829-10:bedroom:controls#child-lock" }
String Bedroom_AP_Function "Function" <text> { channel="philipsair:ac3829-10:bedroom:controls#function" }
Number:Dimensionless Bedroom_AP_TargetHumidity "Humidity Setpoint" <humidity> { channel="philipsair:ac3829-10:bedroom:controls#target-humidity" }
Number:Dimensionless Bedroom_AP_Humidity "Humidity" <humidity> { channel="philipsair:ac3829-10:bedroom:sensors#humidity" }
Number:Temperature Bedroom_AP_Temperature "Temperature" <temperature> { channel="philipsair:ac3829-10:bedroom:sensors#temperature" }
Number:Dimensionless Bedroom_AP_WaterLevel "Water Level" <cistern> { channel="philipsair:ac3829-10:bedroom:sensors#water-level" }
Number:Time Bedroom_AP_WickFilter "Wick" <text> { channel="philipsair:ac3829-10:bedroom:filters#wick-filter-life" }
Switch Office_AP_Power "Power" <switch> { channel="philipsair:coap:office:controls#power" }
Number:Density Office_AP_PM25 "PM2.5" <smoke> { channel="philipsair:coap:office:sensors#pm25" }
# Sitemap Configuration
sitemap philipsair label="Air Purifiers" {
Frame label="Living Room" {
Switch item=LivingRoom_AP_Power
Selection item=LivingRoom_AP_FanSpeed
Selection item=LivingRoom_AP_Mode
Setpoint item=LivingRoom_AP_Timer minValue=0 maxValue=5 step=1
Text item=LivingRoom_AP_TimerLeft
Switch item=LivingRoom_AP_ButtonLight
Selection item=LivingRoom_AP_Index
Text item=LivingRoom_AP_PM25
Text item=LivingRoom_AP_Allergen
Text item=LivingRoom_AP_PreFilter
Text item=LivingRoom_AP_HepaFilter
Text item=LivingRoom_AP_CarbonFilter
}
Frame label="Bedroom" {
Switch item=Bedroom_AP_Power
Selection item=Bedroom_AP_Function
Setpoint item=Bedroom_AP_TargetHumidity minValue=40 maxValue=70 step=10
Text item=Bedroom_AP_Humidity
Text item=Bedroom_AP_Temperature
Text item=Bedroom_AP_WaterLevel
}
Frame label="Office" {
Switch item=Office_AP_Power
Text item=Office_AP_PM25
}
}