##########################################################################################
# Room Fan Control
##########################################################################################
#
# TITLE:
#   Room Fan Control
#
# FILE:
#   packages/room_fan_control.yaml
#
# VERSION:
#   V1.1 2026-07-20
#
# VERSION HISTORY:
#   V1.1 2026-07-20
#     - Added structured documentation for all three bedroom fans.
#     - Documented the master-bedroom feedback loop and command-only controls.
#
#   V1.0
#     - Initial Tasmota and Sonoff iFan02 fan controls.
#
# PURPOSE:
#   Controls the master-bedroom, Bedroom 2, and Bedroom 3 ceiling-fan speeds
#   through Tasmota MQTT commands and Home Assistant dropdown helpers.
#
# SPEED MAPPING:
#   - 0 = Off
#   - 1 = Low
#   - 2 = Medium
#   - 3 = High
#
# MASTER BEDROOM:
#   - Queries FanSpeed when Home Assistant starts.
#   - Listens to Tasmota RESULT and STATE topics for device feedback.
#   - Synchronizes the numeric and dropdown helpers with actual device state.
#   - Uses optimistic local updates until MQTT feedback corrects the helpers.
#   - Provides a button that cycles through speeds 1, 2, 3, and 0.
#
# BEDROOMS 2 AND 3:
#   - Dropdown changes publish FanSpeed commands to each Tasmota device.
#   - These controls are command-only and do not synchronize from feedback.
#   - Their displayed dropdown state may not reflect physical or external changes.
#
# MQTT COMMAND TOPICS:
#   - Master bedroom: cmnd/tasmo-ifan02-3793-bedrm1-1/FanSpeed
#   - Bedroom 2: cmnd/tasmo-ifan02-7042-bedrm2/FanSpeed
#   - Bedroom 3: cmnd/tasmo-ifan02-3497-bedrm3/FanSpeed
#
# DEPENDENCIES:
#   - The three Tasmota devices must accept FanSpeed values from 0 through 3.
#   - Master-bedroom feedback uses its RESULT and STATE MQTT topics.
#
##########################################################################################

input_select:
  master_bedroom_fan_set:
    name: Master Bedroom Fan Speed
    initial: "Off"
    options:
      - "Off"
      - "Low"
      - "Medium"
      - "High"
  bedroom_2_fan_set:
    name: Bedroom 2 Fan Speed
    initial: "Off"
    options:
      - "Off"
      - "Low"
      - "Medium"
      - "High"
  bedroom_3_fan_set:
    name: Bedroom 3 Fan Speed
    initial: "Off"
    options:
      - "Off"
      - "Low"
      - "Medium"
      - "High"

##########################################################################################
# MASTER BEDROOM FAN - Helpers
##########################################################################################
input_number:
  master_bedroom_fan_speed_numeric:
    name: Master Bedroom Fan Speed (Numeric)
    min: 0
    max: 3
    step: 1
    mode: box

template:
  - button:
      - name: Bedroom 1 Fan Speed Change
        unique_id: bedroom_1_fan_speed_change
        icon: mdi:fan
        press:
          - variables:
              cur: "{{ states('input_number.master_bedroom_fan_speed_numeric') | int(0) }}"
              nxt: "{{ (cur + 1) if (cur < 3) else 0 }}"
          - service: mqtt.publish
            data:
              topic: cmnd/tasmo-ifan02-3793-bedrm1-1/FanSpeed
              payload: "{{ nxt }}"
          # Optimistic local update (MQTT will correct if needed)
          - service: input_number.set_value
            data:
              entity_id: input_number.master_bedroom_fan_speed_numeric
              value: "{{ nxt }}"
          - service: input_select.select_option
            data:
              entity_id: input_select.master_bedroom_fan_set
              option: >-
                {% set m = {0:'Off',1:'Low',2:'Medium',3:'High'} %}
                {{ m[nxt] }}

automation:
  ########################################################################################
  # MASTER BEDROOM FAN - Query on HA start (fixes wrong value after reboots)
  ########################################################################################
  - id: master_bedroom_fan_query_on_ha_start
    initial_state: true
    alias: Master Bedroom Fan - Query FanSpeed on HA Start
    description: "Requests the current master-bedroom FanSpeed when Home Assistant starts."
    trigger:
      - platform: homeassistant
        event: start
    action:
      - service: mqtt.publish
        data:
          topic: cmnd/tasmo-ifan02-3793-bedrm1-1/FanSpeed
          payload: ""

  ########################################################################################
  # MASTER BEDROOM FAN - Sync helpers from Tasmota MQTT
  ########################################################################################
  - id: master_bedroom_fan_sync_from_mqtt
    initial_state: true
    alias: Master Bedroom Fan - Sync Helpers From MQTT FanSpeed
    description: "Synchronizes the master-bedroom fan helpers from Tasmota MQTT feedback."
    trigger:
      - platform: mqtt
        topic: stat/tasmo-ifan02-3793-bedrm1-1/RESULT
      - platform: mqtt
        topic: tele/tasmo-ifan02-3793-bedrm1-1/STATE
    condition:
      - condition: template
        value_template: "{{ trigger.payload_json is defined and (trigger.payload_json.FanSpeed is defined) }}"
    action:
      - variables:
          spd: "{{ trigger.payload_json.FanSpeed | int(0) }}"
          opt: >-
            {% set m = {0:'Off',1:'Low',2:'Medium',3:'High'} %}
            {{ m[spd] }}
      - service: input_number.set_value
        data:
          entity_id: input_number.master_bedroom_fan_speed_numeric
          value: "{{ spd }}"
      # Only update dropdown if it differs (avoid loops)
      - condition: template
        value_template: "{{ states('input_select.master_bedroom_fan_set') != opt }}"
      - service: input_select.select_option
        data:
          entity_id: input_select.master_bedroom_fan_set
          option: "{{ opt }}"

  ########################################################################################
  # MASTER BEDROOM FAN - Set speed from dropdown (improved)
  ########################################################################################
  - id: set_the_master_bedroom_fan
    initial_state: true
    alias: Set the Master Bedroom Fan
    description: "Publishes master-bedroom fan speed changes and updates the numeric helper optimistically."
    trigger:
      - platform: state
        entity_id: input_select.master_bedroom_fan_set
    variables:
      desired: >-
        {% set mapping = { 'Off':0, 'Low':1, 'Medium':2, 'High':3 } %}
        {{ mapping.get(trigger.to_state.state, 0) }}
      current: "{{ states('input_number.master_bedroom_fan_speed_numeric') | int(0) }}"
    condition:
      - condition: template
        value_template: "{{ desired != current }}"
    action:
      - service: mqtt.publish
        data:
          topic: cmnd/tasmo-ifan02-3793-bedrm1-1/FanSpeed
          payload: "{{ desired }}"
      # Optimistic local update (MQTT will correct if needed)
      - service: input_number.set_value
        data:
          entity_id: input_number.master_bedroom_fan_speed_numeric
          value: "{{ desired }}"

  ########################################################################################
  # BEDROOM 2 FAN - Command Only
  ########################################################################################
  - id: set_bedroom_2_fan
    initial_state: true
    alias: Set Bedroom 2 Fan Speed
    description: "Publishes Bedroom 2 fan speed dropdown changes to Tasmota."
    trigger:
      entity_id: input_select.bedroom_2_fan_set
      platform: state
    action:
      service: mqtt.publish
      data:
        topic: cmnd/tasmo-ifan02-7042-bedrm2/FanSpeed
        payload: '{% set mapping = { "Off":"0", "Low":"1",
          "Medium":"2", "High":"3" } %} {% set dta = trigger.to_state.state %}
          {{ mapping[dta] }}
          '

  ########################################################################################
  # BEDROOM 3 FAN - Command Only
  ########################################################################################
  - id: set_bedroom_3_fan
    initial_state: true
    alias: Set Bedroom 3 Fan Speed
    description: "Publishes Bedroom 3 fan speed dropdown changes to Tasmota."
    trigger:
      entity_id: input_select.bedroom_3_fan_set
      platform: state
    action:
      service: mqtt.publish
      data:
        topic: cmnd/tasmo-ifan02-3497-bedrm3/FanSpeed
        payload: '{% set mapping = { "Off":"0", "Low":"1",
          "Medium":"2", "High":"3" } %} {% set dta = trigger.to_state.state %}
          {{ mapping[dta] }}
          '
