Home Assistant: Two fans in production

I have my 2 of my 3 fans up and running in Home assistant. Last one isn’t supported yet.


The boxes in red are the bond elements.

Here are the scripts needed to adjust input booleans and call commands to control the fans so it will remember it’s state.

    #Bond Fan Controls
   script:
      bond_fan_on:
          sequence:
            - condition: template
              value_template: "{{ is_state('input_boolean.' + fan + '_state', 'off') }}"   
            - service: script.bond_fan_set_speed
              data_template:
                fan: "{{ fan }}"
                speed: "{{ states('input_select.' + fan + '_speed') }}" 
      
        bond_fan_off:
          sequence:
             - condition: template
               value_template: "{{ is_state('input_boolean.' + fan + '_state', 'on') }}"
             - service: input_boolean.turn_off
               data_template:
                  entity_id: "{{ 'input_boolean.' + fan + '_state' }}"         
             - service_template: "{{ 'rest_command.' + fan + '_pwr' }}"     
      
        bond_fan_set_speed:
          sequence:
            - condition: template
    value_template: "{{ is_state('input_boolean.' + fan + '_state', 'off') or not is_state('input_select.' + fan + '_speed', speed) }}"
            - condition: template
              value_template: "{{ speed in(states.input_select[fan+'_speed'].attributes.options) }}"
            - service: input_boolean.turn_on
              data_template:
                entity_id: "{{ 'input_boolean.' + fan + '_state' }}"
            - service: input_select.select_option
              data_template:
                entity_id: "{{ 'input_select.' + fan + '_speed' }}"
                option: "{{ speed }}"
            - service_template: >
               {% if speed == 'low' %}
                  {{ 'rest_command.' + fan + '_spd_low' }}
               {% elif speed == 'medium' %}
                  {{ 'rest_command.' + fan + '_spd_medium' }}
               {% elif speed == 'high' %}
                  {{ 'rest_command.' + fan + '_spd_high' }}
               {% endif %}
      
        lr_fan_light_adjust:
          sequence:
            - delay: 00:00:01
            - service: rest_command.lr_fan_light_toggle

The last script I use is for a fan where power turns off the light and if I want the fan off and the light on. If the light is on and the fan powers off this turns it back on. The 1 second delay is to allow bond to send the off command first.

Here are the rest commands I am using to control them.

rest_command:
  lr_fan_light_toggle:
      url: http://<bond IP>/v2/devices/<lr_fan ID>/commands/5e68e953/tx
      method: PUT
      headers: 
        content_type: 'application/json'
        'BOND-Token': !secret bond_token
      payload: '{}'

    lr_fan_spd_low:
      url: http://<bond IP>/v2/devices/<lr_fan ID>/commands/7dfe8fee/tx
      method: PUT
      headers: 
        content_type: 'application/json'
        'BOND-Token': !secret bond_token
      payload: '{}'
  
    lr_fan_spd_medium:
      url: http://<bond IP>/v2/devices/<lr_fan ID>/commands/2e2492b2/tx
      method: PUT
      headers: 
        content_type: 'application/json'
        'BOND-Token': !secret bond_token
      payload: '{}'  
  
    lr_fan_spd_high:
      url: http://<bond IP>/v2/devices/<lr_fan ID>/commands/60e0d6c8/tx
      method: PUT
      headers: 
        content_type: 'application/json'
        'BOND-Token': !secret bond_token
      payload: '{}'
  
    lr_fan_pwr:
      url: http://<bond IP>/v2/devices/<lr_fan ID>/commands/65e454ae/tx
      method: PUT
      headers: 
        content_type: 'application/json'
        'BOND-Token': !secret bond_token
      payload: '{}'    
  
    lr_fan_spd_breeze:
      url: http://<bond IP>/v2/devices/<lr_fan ID>/commands/323eb661/tx
      method: PUT
      headers: 
        content_type: 'application/json'
        'BOND-Token': !secret bond_token
      payload: '{}'
  
    lr_fan_light_dimmer:
      url: http://<bond IP>/v2/devices/<lr_fan ID>/commands/75479e79/tx
      method: PUT
      headers: 
        content_type: 'application/json'
        'BOND-Token': !secret bond_token
      payload: '{}'        
    
    mbr_fan_light_toggle:
      url: http://<bond IP>/v2/devices/<mbr_fan ID>/commands/0000003f/tx
      method: PUT
      headers: 
        content_type: 'application/json'
        'BOND-Token': !secret bond_token
      payload: '{}'
    
    mbr_fan_spd_low:
      url: http://<bond IP>/v2/devices/<mbr_fan ID>/commands/00000033/tx
      method: PUT
      headers: 
        content_type: 'application/json'
        'BOND-Token': !secret bond_token
      payload: '{}'  
  
    mbr_fan_spd_medium:
      url: http://<bond IP>/v2/devices/<mbr_fan ID>/commands/00000039/tx
      method: PUT
      headers: 
        content_type: 'application/json'
        'BOND-Token': !secret bond_token
      payload: '{}'
  
    mbr_fan_spd_high:
      url: http://<bond IP>/v2/devices/<mbr_fan ID>/commands/00000036/tx
      method: PUT
      headers: 
        content_type: 'application/json'
        'BOND-Token': !secret bond_token
      payload: '{}'    
  
    mbr_fan_pwr:
      url: http://<bond IP>/v2/devices/<mbr_fan ID>/commands/0000003c/tx
      method: PUT
      headers: 
        content_type: 'application/json'
        'BOND-Token': !secret bond_token
      payload: '{}'     

Lastly the automations that drive it all.

#Bond-o-mations
automation:    
  - alias: "Living Room Fan Light On"
    trigger:
      platform: state
      entity_id: input_boolean.lr_fan_light
      from: "off"
      to: "on"
    action:
      - service: rest_command.lr_fan_light_toggle

  - alias: "Living Room Fan Light Off"
    trigger:
      platform: state
      entity_id: input_boolean.lr_fan_light
      from: "on"
      to: "off"
    action:
      - service: rest_command.lr_fan_light_toggle

  - alias: "Living Room Fan Light Adjust"
    trigger: 
      platform: state
      entity_id: input_boolean.lr_fan_state
      from: "on"
      to: "off"
    action:
      - service_template: >
         {% if is_state('switch.living_fan_light', 'on') %}
            script.lr_fan_light_adjust
         {% else %}
           script.nothing
         {% endif %}

  - alias: "Master Bedroom Fan Boolean Toggle"
    trigger: 
    - event_data:
        args:
          click_type: single
        command: click
        device_ieee: <zigbee button>
      event_type: zha_event
      platform: event
    action:
    - service: input_boolean.toggle
      entity_id: input_boolean.mbr_fan_light

  - alias: "Master bedroom Fan Light On"
    trigger:
      platform: state
      entity_id: input_boolean.mbr_fan_light
      from: "off"
      to: "on"
    action:
      - service: rest_command.mbr_fan_light_toggle
  
  - alias: "Master bedroom Fan Light Off"
    trigger:
      platform: state
      entity_id: input_boolean.mbr_fan_light
      from: "on"
      to: "off"
    action:
      - service: rest_command.mbr_fan_light_toggle

The “Master Bedroom Fan Boolean Toggle” is a xioami aqara switch that I use as a physical light button so I can have home assistant remember the state if pressed and toggle the light. The “Living Room Fan Light Adjust” will turn the light back on if I power of the fan if it is on. If not it calls a script that just waits 1 second and does nothing. I also have automations to adjust fans when I leave and come home and when I got to sleep as well as just being able to control them from home assistant on my phone or computer.

This was a fun learning project for me and I hope it helps someone else with home assistant.

Edit: I would have just changed the number in the rest commands in home assistant for the various speeds but the YAML code didn’t seem to like that in home assistant so I did individual commands.

2 Likes

Good stuff!

A tip to make this more portable:

mbr_fan_spd_high:
      url: http://<bond IP>/v2/devices/<mbr_fan ID>/commands/00000036/tx
      ...
      payload: '{}'  

This could be changed to

mbr_fan_spd_high:
      url: http://<bond IP>/v2/devices/<mbr_fan ID>/actions/SetSpeed
      ....
      payload: '{"argument": 3 (or whatever speed is "high")}'  

The commands API lets you store signals and describe what actions they perform. The actions API handles choosing the right command to match the action/argument, so you don’t need to track down command IDs.

2 Likes

I realized I left out some of the code needed to run this in home assistant. You also need fan, input_boolean and the input select YAML sections. I forgot just home many lines it took to make this work in home assistant.

fan:
  - platform: template
      fans:
        mbr_fan:
          friendly_name: Master Bedroom Fan"
          value_template: "{{ states('input_boolean.mbr_fan_state') }}"
          speed_template: "{{ states('input_select.mbr_fan_speed') }}"
          speeds:
            - 'high'
            - 'medium'
            - 'low'
     
          turn_on:
            - service: script.bond_fan_on
              data:
                fan: 'mbr_fan'
               
          turn_off:
            - service: script.bond_fan_off
              data:
                fan: 'mbr_fan'
           
          set_speed:
            - service: script.bond_fan_set_speed
              data_template:
                fan: 'mbr_fan'
                speed: "{{ speed }}"
               
        lr_fan:
          friendly_name: "Living Room Fan"
          value_template: "{{ states('input_boolean.lr_fan_state') }}"
          speed_template: "{{ states('input_select.lr_fan_speed') }}"
          speeds:
            - 'high'
            - 'medium'
            - 'low'
     
          turn_on:
            - service: script.bond_fan_on
              data:
                fan: 'lr_fan'
               
          turn_off:
            - service: script.bond_fan_off
              data:
                fan: 'lr_fan'
           
          set_speed:
            - service: script.bond_fan_set_speed
              data_template:
                fan: 'lr_fan'
                speed: "{{ speed }}"

input select

 #Bond Fan Speeds
input_select:  
  lr_fan_speed:
    name: Livingroom Fan Speed
    options:
      - medium
      - low
      - high  

  mbr_fan_speed:
    name: Master Fan Speed
    options:
      - high    
      - low
      - medium

input boolean

input_boolean:
  lr_fan_light:
    name: Living Room Fan light

  lr_fan_state:
    name: Living Room Fan State

  mbr_fan_light:
    name: Master Bedroom Fan Light

  mbr_fan_state:
    name: Master Bedroom Fan State

Thanks @jacob! I tried formatting like that before but I kept screwing up the quotation mark format I guess. You code worked well and I will adjust mine to match.

3 Likes

Awesome work! As soon as I figure out what changed and messed up my hassio install over the last 10 or so updates, and get it to actually start up - I’m going to try this out lol

1 Like

This is great work! Are you working on a HA integration or just leaving it as is? Would like to help get a native integration/component into HA.

I personally don’t know enough yet to get that going. That being said after I finished all this I found this guy was starting one and it is open for testing. https://github.com/nguyer/homeassistant-bond-home

I haven’t used it because I already got mine working the way I like. Might be worth looking at though.

I’d be glad to help any way I can though. I just don’t know any Python yet. I’ve just started on the tutorials.