Use case: Integrating IKEA Starkvind air purifier into openHAB

Software requirements:

Channel definition (replace <your device ID> with your device ID …):

channels:
  - id: air_quality
    channelTypeUID: mqtt:string
    label: air_quality
    description: ""
    configuration:
      stateTopic: zigbee2mqtt/<your device ID>
      transformationPattern: JSONPATH:$.air_quality
  - id: child_lock
    channelTypeUID: mqtt:switch
    label: child_lock
    description: ""
    configuration:
      commandTopic: zigbee2mqtt/<your device ID>/set/child_lock
      stateTopic: zigbee2mqtt/<your device ID>
      transformationPattern: JSONPATH:$.child_lock
      off: UNLOCK
      on: LOCK
  - id: fan_mode
    channelTypeUID: mqtt:string
    label: fan_mode
    description: ""
    configuration:
      commandTopic: zigbee2mqtt/<your device ID>/set/fan_mode
      stateTopic: zigbee2mqtt/<your device ID>
      transformationPattern: JSONPATH:$.fan_mode
  - id: fan_state
    channelTypeUID: mqtt:switch
    label: fan_state
    description: ""
    configuration:
      commandTopic: zigbee2mqtt/<your device ID>/set/fan_state
      stateTopic: zigbee2mqtt/<your device ID>
      transformationPattern: JSONPATH:$.fan_state
  - id: pm25
    channelTypeUID: mqtt:number
    label: pm25
    description: ""
    configuration:
      stateTopic: zigbee2mqtt/<your device ID>
      transformationPattern: JSONPATH:$.pm25
      unit: µg/m³
  - id: led_enable
    channelTypeUID: mqtt:switch
    label: led_enable
    description: ""
    configuration:
      commandTopic: zigbee2mqtt/<your device ID>/set/led_enable
      stateTopic: zigbee2mqtt/<your device ID>
      transformationPattern: JSONPATH:$.led_enable
      off: "false"
      on: "true"
  - id: replace_filter
    channelTypeUID: mqtt:switch
    label: replace_filter
    description: ""
    configuration:
      stateTopic: zigbee2mqtt/<your device ID>
      transformationPattern: JSONPATH:$.replace_filter
      off: "false"
      on: "true"
  - id: update_state
    channelTypeUID: mqtt:string
    label: update_state
    description: ""
    configuration:
      stateTopic: zigbee2mqtt/<your device ID>
      transformationPattern: JSONPATH:$.update.state
      off: "false"
      on: "true"
  - id: last_seen
    channelTypeUID: mqtt:datetime
    label: last_seen
    description: ""
    configuration:
      stateTopic: zigbee2mqtt/<your device ID>
      transformationPattern: JSONPATH:$.last_seen
  - id: linkquality
    channelTypeUID: mqtt:number
    label: linkquality
    description: ""
    configuration:
      stateTopic: zigbee2mqtt/<your device ID>
      transformationPattern: JSONPATH:$.linkquality
      unit: lqi
  - id: fan_speed
    channelTypeUID: mqtt:number
    label: fan_speed
    description: ""
    configuration:
      stateTopic: zigbee2mqtt/<your device ID>
      transformationPattern: JSONPATH:$.fan_speed

UI (quite ugly, just a PoC …):


- component: oh-list-card
          config:
            title: "ZB Luftfilter #1"
          slots:
            default:
              - component: oh-label-item
                config:
                  title: PM 2.5
                  icon: f7:cloud_fog
                  action: analyzer
                  actionAnalyzerItems:
                    - ZBLuftfilter1_pm25
                  item: ZBLuftfilter1_pm25
              - component: oh-label-item
                config:
                  item: ZBLuftfilter1_air_quality
                  icon: f7:table
                  title: Luftqualität
              - component: oh-toggle-item
                config:
                  title: Status
                  icon: oh:switch
                  item: ZBLuftfilter1_fan_state
                  iconUseState: true
              - component: oh-input-item
                config:
                  title: Modus
                  icon: oh:fan
                  sendButton: true
                  required: true
                  validate: false
                  item: ZBLuftfilter1_fan_mode
                  inputmode: text
                  name: Modus
                  type: type="text"
              - component: oh-label-item
                config:
                  item: ZBLuftfilter1_fan_speed
                  title: Geschwindigkeit
                  icon: oh:fan
                  action: analyzer
                  actionAnalyzerItems:
                    - ZBLuftfilter1_fan_speed
              - component: oh-toggle-item
                config:
                  title: LED
                  icon: oh:lightbulb
                  item: ZBLuftfilter1_led_enable
                  iconUseState: true
              - component: oh-toggle-item
                config:
                  title: Kindersicherung
                  icon: oh:baby_1
                  item: ZBLuftfilter1_child_lock
                  iconUseState: true
              - component: oh-toggle-item
                config:
                  title: Filter ersetzen
                  icon: f7:wrench
                  item: ZBLuftfilter1_replace_filter
                  iconUseState: false
              - component: oh-label-item
                config:
                  item: ZBLuftfilter1_update_state
                  title: Update
                  icon: oh:settings
              - component: oh-label-item
                config:
                  item: ZBLuftfilter1_linkquality
                  icon: oh:network
                  title: Link-Qualität
                  action: analyzer
                  actionAnalyzerItems:
                    - ZBLuftfilter1_linkquality
              - component: oh-label-item
                config:
                  item: ZBLuftfilter1_last_seen
                  title: Last seen
                  icon: oh:time

Results:

Remarks:
To increase the resolution of the PM 2.5 values use the device specific Zigbee2MQTT option pm25_precision (not tested).

Further reading:

1 Like

Super cool. I’m looking at the fornufting to stick them to the walls instead. Esp8266, a voltage step down and tasmota should be sufficient to get it into openHAB :smiley: but this is super nice too :slight_smile: