OK, I added the oscillation mode as a separate input_select and here’s my solution:
1 setup input_select: First I define an input select containing the modes starting with a number (I extract the number in the script to cycle correctly, so this is mandatory):
input_select:
ventilatore_sala_oscillation_mode:
name: 'Ventilatore sala oscillazione'
icon: mdi:arrow-decision-outline
options:
- '1 - off'
- '2 - destra sinistra'
- '3 - su giù'
- '4 - misto'
2. revert to 1 at every turno_on: Then in the Template Fan I add an action on turn_on so that the input_select is back to 1 at startup (remember that my fan start from fresh no oscillation, fan speed 1 at every startup - it may or may not be necessary for your setup but then I’d lock or hide the control when the fan is off), my full turn_on automation goes like this:
turn_on:
- condition: state
entity_id: input_boolean.ventilatore_sala_stato
state: 'off'
- service: remote.send_command
data:
entity_id: remote.broadlink
device: ventilatore
command: power
- service: input_select.select_option
data:
entity_id: input_select.ventilatore_sala_oscillation_mode
option: '1 - off'
- service: input_boolean.turn_on
entity_id: input_boolean.ventilatore_sala_stato
- service: input_text.set_value
data:
entity_id: input_text.ventilatore_sala_fan_speed
value: 1
I added the same automation on turn_off, even if it’s not necessary, but it’s a sort of “reset” when turning off.
3 - automate script launch when the input_select changes Then I setup an automation that feeds the script with the from and to state of input_select:
- id: '1598781094128'
alias: Fan - modo oscillazione
description: ''
trigger:
- entity_id: input_select.ventilatore_sala_oscillation_mode
platform: state
condition:
- condition: state
entity_id: fan.ventilatore_sala
state: 'on'
action:
- data_template:
oscillation_mode: '{{ trigger.to_state.state }}'
oscillation_mode_from: '{{ trigger.from_state.state }}'
service: python_script.fan_oscillation
mode: single
**4 - The script: ** and finally the modified script goes like this, set broadlink IP, code and number of states in the input_select accordingly to your setup (I’m no python programmer so excuse if it’s not very clean code):
# Set code to whatever RF code your fan uses for oscillation mode.
code = 'JgByAJWUETERMRIxETERMRIxEVERMhExETESMRFREVESURExETIRMZaUETERMREyETERMRExElERMhExETERMRJREVERUhExETESAAGhAAEpSBMABo4AAShKEgAGjgABKEoRAAaPAAEnShIACPUGAAzFCAANBQAAAAA='
oscillation_raw = data.get('oscillation_mode')
status_oscillation_raw = data.get('oscillation_mode_from')
# status_oscillation_raw = hass.states.get('input_select.ventilatore_sala_oscillation_mode')
# extracting the first charachter that is the mode in numeric form
# maybe define an array and compare?
oscillation = oscillation_raw[0]
# logger.warning('to:'+ oscillation)
# logger.warning(oscillation_raw[0])
status_oscillation = status_oscillation_raw[0]
# logger.warning('from:' + status_oscillation)
# logger.warning(status_oscillation_raw[0])
if oscillation is not None:
oscillation = int(oscillation)
# last_oscillation = int(status_oscillation.state) if status_oscillation.state else 1
last_oscillation = int(status_oscillation)
if 1 <= oscillation <= 4:
if oscillation > last_oscillation:
loop = oscillation - last_oscillation
else:
loop = (4 - last_oscillation) + oscillation
# Set the IP address to match the one used by your Broadlink device
service_data = {'host':'192.168.0.195', 'packet':'{}'.format(code)}
for i in range(loop):
hass.services.call('broadlink', 'send', service_data, False)
time.sleep(0.5)
else:
logger.warning('<fan_oscillation_control> Received fan oscillation is invalid ({})'.format(fan_oscillation))
else:
logger.warning('<fan_oscillation_control> Received fan oscillation is invalid (None)')
All improvements are strongly welcome.
Thanks again to everyone that allowed me to get it to work.