question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[Device Support Request] Ikea Starkvind Air Purifier

See original GitHub issue

Is your feature request related to a problem? Please describe. N/A

Describe the solution you’d like

When adding the Starkvind in ZHA/home assistant only the fan is recognized. The device also support other sensors but those are not exposed. Would it be possible to also expose the other sensors which are supported by this device; pm25, air_quality, led_enable, child_lock, replace_filter.

Device signature - this can be acquired by removing the device from ZHA and pairing it again from the add devices screen. Be sure to add the entire content of the log panel after pairing the device to a code block below this line.

{
  "node_descriptor": "NodeDescriptor(logical_type=<LogicalType.Router: 1>, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=<FrequencyBand.Freq2400MHz: 8>, mac_capability_flags=<MACCapabilityFlags.AllocateAddress|RxOnWhenIdle|MainsPowered|FullFunctionDevice: 142>, manufacturer_code=4476, maximum_buffer_size=82, maximum_incoming_transfer_size=82, server_mask=11264, maximum_outgoing_transfer_size=82, descriptor_capability_field=<DescriptorCapability.NONE: 0>, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=False, *is_full_function_device=True, *is_mains_powered=True, *is_receiver_on_when_idle=True, *is_router=True, *is_security_capable=False)",
  "endpoints": {
    "1": {
      "profile_id": 260,
      "device_type": "0x0007",
      "in_clusters": [
        "0x0000",
        "0x0003",
        "0x0004",
        "0x0005",
        "0x0202",
        "0xfc57",
        "0xfc7d"
      ],
      "out_clusters": [
        "0x0019",
        "0x0400",
        "0x042a"
      ]
    },
    "242": {
      "profile_id": 41440,
      "device_type": "0x0061",
      "in_clusters": [],
      "out_clusters": [
        "0x0021"
      ]
    }
  },
  "manufacturer": "IKEA of Sweden",
  "model": "STARKVIND Air purifier",
  "class": "zigpy.device.Device"
}
New device 0x4d79 (b4:e3:f9:ff:fe:2b:07:3f) joined the network
[0x4d79] Scheduling initialization
Received frame on uninitialized device <Device model=None manuf=None nwk=0x4D79 ieee=b4:e3:f9:ff:fe:2b:07:3f is_initialized=False> from ep 0 to ep 0, cluster ZDOCmd.Device_annce: b'\xFF\x79\x4D\x3F\x07\x2B\xFE\xFF\xF9\xE3\xB4\x8E'
[0x4d79:zdo] ZDO request ZDOCmd.Device_annce: [0x4D79, b4:e3:f9:ff:fe:2b:07:3f, 142]
Tries remaining: 3
[0x4d79] Requesting 'Node Descriptor'
Tries remaining: 2
[0x4d79] Extending timeout for 0x13 request
Received frame on uninitialized device <Device model=None manuf=None nwk=0x4D79 ieee=b4:e3:f9:ff:fe:2b:07:3f is_initialized=False> from ep 0 to ep 0, cluster ZDOCmd.Node_Desc_rsp: b'\x13\x00\x79\x4D\x01\x40\x8E\x7C\x11\x52\x52\x00\x00\x2C\x52\x00\x00'
[0x4d79] Got Node Descriptor: NodeDescriptor(logical_type=<LogicalType.Router: 1>, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=<FrequencyBand.Freq2400MHz: 8>, mac_capability_flags=<MACCapabilityFlags.AllocateAddress|RxOnWhenIdle|MainsPowered|FullFunctionDevice: 142>, manufacturer_code=4476, maximum_buffer_size=82, maximum_incoming_transfer_size=82, server_mask=11264, maximum_outgoing_transfer_size=82, descriptor_capability_field=<DescriptorCapability.NONE: 0>, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=False, *is_full_function_device=True, *is_mains_powered=True, *is_receiver_on_when_idle=True, *is_router=True, *is_security_capable=False)
[0x4d79] Discovering endpoints
Tries remaining: 3
Received frame on uninitialized device <Device model=None manuf=None nwk=0x4D79 ieee=b4:e3:f9:ff:fe:2b:07:3f is_initialized=False> from ep 0 to ep 0, cluster ZDOCmd.Active_EP_rsp: b'\x14\x00\x79\x4D\x02\x01\xF2'
[0x4d79] Discovered endpoints: [1, 242]
[0x4d79] Initializing endpoints [<Endpoint id=1 in=[] out=[] status=<Status.NEW: 0>>, <Endpoint id=242 in=[] out=[] status=<Status.NEW: 0>>]
[0x4d79:1] Discovering endpoint information
Tries remaining: 3
Received frame on uninitialized device <Device model=None manuf=None nwk=0x4D79 ieee=b4:e3:f9:ff:fe:2b:07:3f is_initialized=False> from ep 0 to ep 0, cluster ZDOCmd.Simple_Desc_rsp: b'\x15\x00\x79\x4D\x1C\x01\x04\x01\x07\x00\x01\x07\x00\x00\x03\x00\x04\x00\x05\x00\x02\x02\x57\xFC\x7D\xFC\x03\x19\x00\x00\x04\x2A\x04'
[0x4d79:1] Discovered endpoint information: SizePrefixedSimpleDescriptor(endpoint=1, profile=260, device_type=7, device_version=1, input_clusters=[0, 3, 4, 5, 514, 64599, 64637], output_clusters=[25, 1024, 1066])
[0x4d79:242] Discovering endpoint information
Tries remaining: 3
Received frame on uninitialized device <Device model=None manuf=None nwk=0x4D79 ieee=b4:e3:f9:ff:fe:2b:07:3f is_initialized=False> from ep 0 to ep 0, cluster ZDOCmd.Simple_Desc_rsp: b'\x16\x00\x79\x4D\x0A\xF2\xE0\xA1\x61\x00\x00\x00\x01\x21\x00'
[0x4d79:242] Discovered endpoint information: SizePrefixedSimpleDescriptor(endpoint=242, profile=41440, device_type=97, device_version=0, input_clusters=[], output_clusters=[33])
[0x4d79:1:0x0000] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=23 command_id=Command.Read_Attributes_rsp>
[0x4d79] Read model 'STARKVIND Air purifier' and manufacturer 'IKEA of Sweden' from <Endpoint id=1 in=[basic:0x0000, identify:0x0003, groups:0x0004, scenes:0x0005, fan:0x0202, manufacturer_specific:0xFC57, manufacturer_specific:0xFC7D] out=[ota:0x0019, illuminance:0x0400, pm25:0x042A] status=<Status.ZDO_INIT: 1>>
[0x4d79] Discovered basic device information for <Device model='STARKVIND Air purifier' manuf='IKEA of Sweden' nwk=0x4D79 ieee=b4:e3:f9:ff:fe:2b:07:3f is_initialized=True>
Device is initialized <Device model='STARKVIND Air purifier' manuf='IKEA of Sweden' nwk=0x4D79 ieee=b4:e3:f9:ff:fe:2b:07:3f is_initialized=True>
Checking quirks for IKEA of Sweden STARKVIND Air purifier (b4:e3:f9:ff:fe:2b:07:3f)
Considering <class 'zhaquirks.ikea.tradfriplug.TradfriPlug'>
Fail because endpoint list mismatch: {1, 2, 242} {1, 242}
Considering <class 'zhaquirks.xbee.xbee_io.XBeeSensor'>
Fail because endpoint list mismatch: {232, 230} {1, 242}
Considering <class 'zhaquirks.xbee.xbee3_io.XBee3Sensor'>
Fail because endpoint list mismatch: {232, 230} {1, 242}
Considering <class 'zhaquirks.smartthings.tag_v4.SmartThingsTagV4'>
Fail because endpoint list mismatch: {1} {1, 242}
Considering <class 'zhaquirks.smartthings.multi.SmartthingsMultiPurposeSensor'>
Fail because endpoint list mismatch: {1} {1, 242}
Considering <class 'zhaquirks.netvox.z308e3ed.Z308E3ED'>
Fail because endpoint list mismatch: {1} {1, 242}
Considering <class 'zhaquirks.gledopto.soposhgu10.SoposhGU10'>
Fail because endpoint list mismatch: {11, 13} {1, 242}
Considering <class 'bellows.zigbee.application.EZSPCoordinator'>
Fail because endpoint list mismatch: {1} {1, 242}
device - 0x4D79:b4:e3:f9:ff:fe:2b:07:3f entering async_device_initialized - is_new_join: True
device - 0x4D79:b4:e3:f9:ff:fe:2b:07:3f has joined the ZHA zigbee network
[0x4D79](STARKVIND Air purifier): started configuration
[0x4D79:ZDO](STARKVIND Air purifier): 'async_configure' stage succeeded
[0x4D79:1:0x0000]: finished channel configuration
[0x4D79:1:0x0019]: finished channel configuration
Error handling '_save_attribute' event with (b4:e3:f9:ff:fe:2b:07:3f, 1, 0, 4, 'IKEA of Sweden') params: FOREIGN KEY constraint failed
Error handling '_save_attribute' event with (b4:e3:f9:ff:fe:2b:07:3f, 1, 0, 5, 'STARKVIND Air purifier') params: FOREIGN KEY constraint failed
[0x4D79:1:0x0202]: bound 'fan' cluster: Status.SUCCESS
[0x4d79:1:0x0202] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=25 command_id=Command.Configure_Reporting_rsp>
[0x4D79:1:0x0202]: Successfully configured reporting for '{'fan_mode': (5, 900, 1)}' on 'fan' cluster: [ConfigureReportingResponseRecord(status=0)]
[0x4D79:1:0x0202]: finished channel configuration
[0x4D79:1:0x0202]: 'async_configure' stage succeeded
[0x4D79:1:0x0000]: 'async_configure' stage succeeded
[0x4D79:1:0x0019]: 'async_configure' stage succeeded
[0x4D79](STARKVIND Air purifier): completed configuration
[0x4D79](STARKVIND Air purifier): stored in registry: ZhaDeviceEntry(name='IKEA of Sweden STARKVIND Air purifier', ieee='b4:e3:f9:ff:fe:2b:07:3f', last_seen=1639420791.6012802)
[0x4d79:1:0x0003] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=26 command_id=Command.Default_Response>
[0x4D79:1:0x0003]: executed 'trigger_effect' command with args: '(2, 0)' kwargs: '{}' result: [64, <Status.SUCCESS: 0>]
[0x4D79](STARKVIND Air purifier): started initialization
[0x4D79:ZDO](STARKVIND Air purifier): 'async_initialize' stage succeeded
[0x4D79:1:0x0202]: initializing channel: from_cache: False
[0x4D79:1:0x0000]: initializing channel: from_cache: False
[0x4D79:1:0x0000]: finished channel initialization
[0x4D79:1:0x0019]: initializing channel: from_cache: False
[0x4D79:1:0x0019]: finished channel initialization
[0x4d79:1:0x0202] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=27 command_id=Command.Read_Attributes_rsp>
[0x4D79:1:0x0202]: Attribute report 'Fan Control'[fan_mode_sequence] = FanModeSequence.Low_Med_High_Auto
[0x4d79:1:0x0202] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=28 command_id=Command.Read_Attributes_rsp>
[0x4D79:1:0x0202]: Attribute report 'Fan Control'[fan_mode] = FanMode.Off
[0x4D79:1:0x0202]: finished channel initialization
[0x4D79:1:0x0202]: 'async_initialize' stage succeeded
[0x4D79:1:0x0000]: 'async_initialize' stage succeeded
[0x4D79:1:0x0019]: 'async_initialize' stage succeeded
[0x4D79](STARKVIND Air purifier): power source: Mains
[0x4D79](STARKVIND Air purifier): completed initialization

Additional context Add any other context or screenshots about the feature request here.

Screenshot 2021-12-13 19 43 15

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:10
  • Comments:30 (17 by maintainers)

github_iconTop GitHub Comments

11reactions
arnemauercommented, May 28, 2022

I’ve started with a quirk 😃

"""Device handler for IKEA of Sweden STARKVIND Air purifier."""
from zigpy.profiles import zha
from zigpy.quirks import CustomDevice
from zigpy.zcl.clusters.general import (
    Basic,
    Groups,
    Identify,
    Ota,
    PollControl,
    Scenes,
    GreenPowerProxy,
)
from zigpy.zcl.clusters.hvac import Fan
from zhaquirks.ikea import IKEA
from zigpy.zcl.clusters.measurement import (
    IlluminanceMeasurement,
    PM25,
)

from zhaquirks.const import (
    CLUSTER_ID,
    DEVICE_TYPE,
    ENDPOINT_ID,
    ENDPOINTS,
    INPUT_CLUSTERS,
    MODELS_INFO,
    OUTPUT_CLUSTERS,
    PROFILE_ID,
)

#IKEA_CLUSTER_ID = 0xFC7C  # decimal = 64636

WWAH_CLUSTER_ID = 0xFC57  # decimal = 64599
IKEA_CLUSTER_UNKNOWN_ID = 0xFC7D

class IkeaSTARKVIND(CustomDevice):
    """STARKVIND Air purifier by IKEA of Sweden."""

    signature = {
        # <SimpleDescriptor endpoint=1 profile=260 device_type=7 (0x0007)
        # device_version=0
        # input_clusters=[0, 3, 4, 5, 514, 64599, 64637] output_clusters=[25, 1024, 1066]>
        MODELS_INFO: [(IKEA, "STARKVIND Air purifier")],
        ENDPOINTS: {
            1: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.COMBINED_INTERFACE,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,           #0
                    Identify.cluster_id,        #3 
                    Groups.cluster_id,          #4
                    Scenes.cluster_id,          #5
                    Fan.cluster_id,             #514    0x0202
                    WWAH_CLUSTER_ID,            #64599  0xFC57
                    IKEA_CLUSTER_UNKNOWN_ID,    #64637  0xFC7D
                ],
                 OUTPUT_CLUSTERS: [
                    Ota.cluster_id,                     #25      0x0019
                    IlluminanceMeasurement.cluster_id,  #1024    0x0400
                    PM25.cluster_id,                             #1066    0x042A PM2.5 Measurement Cluster
                ],
            },
            # <SimpleDescriptor endpoint=242 profile=41440 device_type=97
            # device_version=0
            # input_clusters=[33] output_clusters=[33]>
            242: {
                PROFILE_ID: 0xA1E0, # 41440 (dec)
                DEVICE_TYPE: 0x0061,
                INPUT_CLUSTERS: [],
                OUTPUT_CLUSTERS: [
                    GreenPowerProxy.cluster_id, #0x0021 = GreenPowerProxy.cluster_id?
                ], 
            },
        },
    }

    replacement = {
        ENDPOINTS: {
            1: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.COMBINED_INTERFACE,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,           #0
                    Identify.cluster_id,        #3 
                    Groups.cluster_id,          #4
                    Scenes.cluster_id,          #5
                    Fan.cluster_id,             #514
                    WWAH_CLUSTER_ID,            #64599  0xFC57
                    IKEA_CLUSTER_UNKNOWN_ID,    #64637  0xFC7D
                ],
                OUTPUT_CLUSTERS: [
                    Ota.cluster_id,                     #25      0x0019
                    IlluminanceMeasurement.cluster_id,  #1024    0x0400
                    PM25.cluster_id,                             #1066    0x042A PM2.5 Measurement Cluster
                ],
            }
        }
    }
    

Step 1: The quirk is recognised 😃

7reactions
arnemauercommented, Jun 1, 2022

class PM25(_ConcentrationMixin, Cluster) is already in the zigpy code. https://github.com/zigpy/zigpy/pull/683/files#diff-ec4c5179b55bb221fdcf288218a3e4ee5ccabcbefa8497468b6231429f669174

But this type of sensor is not available in HA. I created a pull request to add the Particulate Matter 2.5 sensor to ZHA component. 😃

=============================

Here is a scan of all attribute values of the Starkvind: STARKVIND Air purifier_IKEA of Sweden_fffea8b421_scan_results.txt

Read more comments on GitHub >

github_iconTop Results From Across the Web

IKEA air purifiers and filters
Improve air quality indoors with IKEA air purifiers. Find out how to install, connect to your smart home and change a filter, plus...
Read more >
Ikea Starkvind Device Handler [request]
... now i'm wondering (since i cannot find any topics about it) is there already a Device Handler for the IKEA Starkvind air...
Read more >
Ikea STARKVIND smart air purifier hands on review including ...
This is the a video of the Ikea STARKVIND smart air purifier hands on review including HomeKit.Follow me for all the latest on...
Read more >
Ikea Air Purifier Support? (Starkvind) - Hubitat Community
What does it show up as in the device page, i.e. what is the "Type" for the device, or the driver? mattstein April...
Read more >
Is assemble-it-yourself smart tech the way of the future?
My Ikea Starkvind air purifier arrived in several pieces that I had to ... with their devices and help them understand how everything...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found