"smart slopes" style fan control

Hello, i have a small python script running on my computer to automatically adjust air purifier fan levels depending on pollution sensors.

It’s fairly basic: Air quality index > X then use broadlink IR remote to set fan level to Y
I would like to be able to change this using a GUI / widget rather than a script and Google brought me to HA a few days ago.

Air quality index sensors support is already in (Kaiterra), and so is broadlink IR remote support for fans / ACs using SmartIR.
I added IR codes for the air purifier (SmartIR PR in case anyone is looking for IQAir Health Pro 250 IR codes).

I am now looking for a gui or a widget to adjust the (X,Y) curve. Something like the MSI smart slope would be great, where you simply click on a graph to decide what sensor level corresponds to a fan speed

Does it exist already? If not, do you think it would be easy and/or useful for anyone else to put together?

Thanks in advance
Anil
PS: apologies if this has been asked before, i searched the forum and didn’t find anything obvious

No nothing like that exists in home assistant. It would indeed be useful for a lot of things, fan control, light brightness, pump speed etc…

At the moment I implement controls like this with a template function and automation. No GUI to edit it. If I want to edit the response I have to edit the template.

thank you. i have implemented my script’s functionality using automation. it strikes me as overly long and repetitve though. is there a way to factorize this?

- id: '1599312067282'
  alias: IQAir 6
  description: ''
  trigger:
  - entity_id: air_quality.living_room_laseregg_air_quality
    platform: state
  condition:
  - condition: or
    conditions:
    - above: '21'
      condition: numeric_state
      entity_id: air_quality.living_room_laseregg_air_quality
      value_template: '{{ states.air_quality.living_room_laseregg_air_quality.attributes.particulate_matter_2_5
        }}'
    - above: '93'
      condition: numeric_state
      entity_id: air_quality.living_room_laseregg_air_quality
      value_template: '{{ states.air_quality.living_room_laseregg_air_quality.attributes.particulate_matter_10
        }}'
  action:
  - data:
      entity_id: fan.iqair
      speed: six
    entity_id: fan.iqair
    service: fan.set_speed
  mode: single
- id: '1599313526453'
  alias: IQAir 5
  description: ''
  trigger:
  - entity_id: air_quality.living_room_laseregg_air_quality
    platform: state
  condition:
  - condition: or
    conditions:
    - above: '12'
      below: '20.99'
      condition: numeric_state
      entity_id: air_quality.living_room_laseregg_air_quality
      value_template: '{{ states.air_quality.living_room_laseregg_air_quality.attributes.particulate_matter_2_5
        }}'
    - above: '54'
      below: '92.99'
      condition: numeric_state
      entity_id: air_quality.living_room_laseregg_air_quality
      value_template: '{{ states.air_quality.living_room_laseregg_air_quality.attributes.particulate_matter_10
        }}'
  action:
  - data:
      entity_id: fan.iqair
      speed: five
    entity_id: fan.iqair
    service: fan.set_speed
  mode: single
- id: '1599314521058'
  alias: IQAir 4
  description: ''
  trigger:
  - entity_id: air_quality.living_room_laseregg_air_quality
    platform: state
  condition:
  - condition: or
    conditions:
    - above: '10'
      below: '11.99'
      condition: numeric_state
      entity_id: air_quality.living_room_laseregg_air_quality
      value_template: '{{ states.air_quality.living_room_laseregg_air_quality.attributes.particulate_matter_2_5
        }}'
    - above: '42'
      below: '53.99'
      condition: numeric_state
      entity_id: air_quality.living_room_laseregg_air_quality
      value_template: '{{ states.air_quality.living_room_laseregg_air_quality.attributes.particulate_matter_10
        }}'
  action:
  - data:
      entity_id: fan.iqair
      speed: four
    entity_id: fan.iqair
    service: fan.set_speed
  mode: single
- id: '1599314790695'
  alias: IQAir 2
  description: ''
  trigger:
  - entity_id: air_quality.living_room_laseregg_air_quality
    platform: state
  condition:
  - condition: or
    conditions:
    - above: '5'
      below: '9.99'
      condition: numeric_state
      entity_id: air_quality.living_room_laseregg_air_quality
      value_template: '{{ states.air_quality.living_room_laseregg_air_quality.attributes.particulate_matter_2_5
        }}'
    - above: '22'
      below: '41.99'
      condition: numeric_state
      entity_id: air_quality.living_room_laseregg_air_quality
      value_template: '{{ states.air_quality.living_room_laseregg_air_quality.attributes.particulate_matter_10
        }}'
  action:
  - data:
      entity_id: fan.iqair
      speed: two
    entity_id: fan.iqair
    service: fan.set_speed
  mode: single
- id: '1599314909186'
  alias: IQAir
  description: ''
  trigger:
  - entity_id: air_quality.living_room_laseregg_air_quality
    platform: state
  condition:
  - condition: and
    conditions:
    - below: '4.99'
      condition: numeric_state
      entity_id: air_quality.living_room_laseregg_air_quality
      value_template: '{{ states.air_quality.living_room_laseregg_air_quality.attributes.particulate_matter_2_5
        }}'
    - below: '21.99'
      condition: numeric_state
      entity_id: air_quality.living_room_laseregg_air_quality
      value_template: '{{ states.air_quality.living_room_laseregg_air_quality.attributes.particulate_matter_10
        }}'
  action:
  - data: {}
    entity_id: fan.iqair
    service: fan.turn_off
  mode: single

slightly shorter version, all in one automation, using choose to have if/elif/else structure, couldn’t figure out how to factorize further. uses state_attr() and logs to the logbook as well so should be more stable

- id: '1599371220080'
  alias: IQAir
  description: ''
  trigger:
  - entity_id: air_quality.living_room_laseregg_air_quality
    platform: state
  condition: []
  action:
  - choose:
    - conditions:
      - above: '21'
        condition: numeric_state
        entity_id: air_quality.living_room_laseregg_air_quality
        value_template: '{{state_attr(''air_quality.living_room_laseregg_air_quality'',''particulate_matter_2_5'')}}'
      - condition: template
        value_template: '{{ state_attr(''fan.iqair'', ''speed'') != ''six'' }}'
      sequence:
      - data:
          entity_id: fan.iqair
          speed: six
        entity_id: fan.iqair
        service: fan.set_speed
      - data:
          entity_id: fan.iqair
          message: six sent
          name: IQAir
        service: logbook.log
    - conditions:
      - above: '11.99'
        below: '20.99'
        condition: numeric_state
        entity_id: air_quality.living_room_laseregg_air_quality
        value_template: '{{state_attr(''air_quality.living_room_laseregg_air_quality'',''particulate_matter_2_5'')}}'
      - condition: template
        value_template: '{{ state_attr(''fan.iqair'', ''speed'') != ''five'' }}'
      sequence:
      - data:
          entity_id: fan.iqair
          speed: five
        entity_id: fan.iqair
        service: fan.set_speed
      - data:
          entity_id: fan.iqair
          message: five sent
          name: IQAir
        service: logbook.log
    - conditions:
      - above: '10.99'
        below: '11.99'
        condition: numeric_state
        entity_id: air_quality.living_room_laseregg_air_quality
        value_template: '{{state_attr(''air_quality.living_room_laseregg_air_quality'',''particulate_matter_2_5'')}}'
      - condition: template
        value_template: '{{ state_attr(''fan.iqair'', ''speed'') != ''four'' }}'
      sequence:
      - data:
          entity_id: fan.iqair
          speed: four
        entity_id: fan.iqair
        service: fan.set_speed
      - data:
          entity_id: fan.iqair
          message: four sent
          name: IQAir
        service: logbook.log
    - conditions:
      - above: '9.99'
        below: '10.99'
        condition: numeric_state
        entity_id: air_quality.living_room_laseregg_air_quality
        value_template: '{{state_attr(''air_quality.living_room_laseregg_air_quality'',''particulate_matter_2_5'')}}'
      - condition: template
        value_template: '{{ state_attr(''fan.iqair'', ''speed'') != ''three'' }}'
      sequence:
      - data:
          entity_id: fan.iqair
          speed: three
        entity_id: fan.iqair
        service: fan.set_speed
      - data:
          entity_id: fan.iqair
          message: three sent
          name: IQAir
        service: logbook.log
    - conditions:
      - above: '4.99'
        below: '9.99'
        condition: numeric_state
        entity_id: air_quality.living_room_laseregg_air_quality
        value_template: '{{state_attr(''air_quality.living_room_laseregg_air_quality'',''particulate_matter_2_5'')}}'
      - condition: template
        value_template: '{{ state_attr(''fan.iqair'', ''speed'') != ''two'' }}'
      sequence:
      - data:
          entity_id: fan.iqair
          speed: two
        entity_id: fan.iqair
        service: fan.set_speed
      - data:
          entity_id: fan.iqair
          message: two sent
          name: IQAir
        service: logbook.log
    - conditions:
      - below: '4.99'
        condition: numeric_state
        entity_id: air_quality.living_room_laseregg_air_quality
        value_template: '{{state_attr(''air_quality.living_room_laseregg_air_quality'',''particulate_matter_2_5'')}}'
      - condition: state
        entity_id: fan.iqair
        state: 'on'
      sequence:
      - data: {}
        entity_id: fan.iqair
        service: fan.turn_off
      - data:
          entity_id: fan.iqair
          message: turned off
          name: IQAir
        service: logbook.log
    default:
    - data:
        entity_id: fan.iqair
        message: nothing sent
        name: IQAir
      service: logbook.log
  mode: single

now that fan.set_speed has been deprecated, what is the correct way to implement this?
i can’t figure out preset modes using SmartIR fans