SmartIR - Control your Climate, TV and Fan devices via IR/RF controllers

Something similar happened to me too… did this and now its working… dont know if its the best way or what is happening but you could try this :

in Homeassistant try going to “Developer Tools” >> STATES >> Set State…

there search for the Media_player entity…

the state shows as “unknown”, change it to “off” then “Set State”… then go quickly to the dashboard and turn On/ open that media player (before the X seconds of the power sensor delay)…

after that the media_player seems to be is working…

(smartir 1.18, zigbee2mqtt, zs06 controller)

1 Like

WOW! this trick solve my issues with all my newest media player controllers. (Persistent after restarting)
Working for Broadlink and MQTT configurations
Thank you very much

1 Like

thank you for testing it… dont know how i did it :sweat_smile: tried to reproduce the error several times and that solution worked…

1 Like

Hello.

I just purchased a new Hunter Ceiling Fan with remote and a Broadlink RM4 Pro. I wanted to use SmartIR so that I could use it as an entity, but I am having trouble setting it up.

I used the broadlink integration and learned the 4 button remote codes using developer tools (Fan, Light, Up, Down).

I added the following to my configuration.yaml (but receive this message when I view it in File Editor “duplicated mapping key (98:1)”). The YAML check in developer tools allows it to still restart.

# SmartIR Configuration
smartir:

fan:
 - platform: smartir
   name: Master Bedroom Fan
   unique_id: master_bedroom_ceiling_fan
   device_code: 9000
   controller_data: remote.rm4_pro_master_bedroom

I created a Fan code file “9000.json” and placed it in /custom_components/smartir/codes/fan

{
  "manufacturer": "Hunter",
  "supportedModels": [
    "Unknown"
  ],
  "supportedController": "Broadlink",
  "commandsEncoding": "Base64",
  "speed": [
    "up",
    "down",
  ],
  "commands": {
    "Fan": "sMDeAWibBgAMDQ0NDQwNDQwODA0NDQwNDQ0NDA0NDaYaDRkNGg0MGhoNDBoZDhkMDRoaDRgODRkNGQ0aGQ0MGxkNGQ4MGhkNDRoMGhoNDBoMGg0aDBsMGRoMDRoZDQ0aDRkaDRkNDBsZDQwaDRoZDRoNDBoMGwwZDRoNGQ0ZGg4MGQ4ZDBoaDRkNGQ4ZDRkOGQ0ZDRoNDBoaDBoNGA8MGQ0aDQADNA0ODA0MDQ0NDQ0MDQ0MDQ4MDQwNDQ0NpxkNGQ0aDQwaGgwNGRsMGQ4MGhkNGQ4MGg0ZDRoZDQwbGQ0ZDgwaGQ4MGgwaGg0MGgwaDRoMGg0aGA4NGRkNDRoMGhoNGQ0MGxkNDBsMGhkNGg0MGgwbDBkNGwwZDRoZDQwaDhkNGRoNGQ0aDRkNGQ4ZDRkNGg0MGhoMGg0ZDgwZDRoNAAM0DQ0NDQ0MDQ0NDQwNDQwODQwNDA0NDQ2nGQwaDhkNDBkaDQ0ZGg0ZDQ0aGQ0ZDgwaDBsMGhkNDRoZDRoNDBoZDgwaDBsYDgwZDhkNGQ0aDRkaDQwaGQ4MGgwaGg0ZDQwbGQ0MGwwaGQ4ZDA0aDRoMGgwaDRkNGhkNDRoMGgwaGg0ZDRoNGQ0aDRkNGQ4ZDQwbGQwZDhkODBkNGg0ABdw=",
    "Light": "scDQAc6eBgDRCQ4LDwwNDA2mGwwaDRgPDBoYDg0ZGQ0aDQ0ZGg0ZDQwbDBoMGxkNDBsZDRkNDRoZDQ0aDBkaDgwZDRoNGQ0aDRkZDQ4ZGQ0OGQwaGg0ZDQwbGQ0MGwwaGQwbDA0ZDhkZDRoNDRkNGg0ZDRoMGgwbDBoMGhoNGQ0MGwwZGwwaDRkOGQwZDhkNGQ0aDQ0AAzUNDA0NDgwNDA0MDg0NDA0MDQ4NDA0MDaYbDBoMGwwNGRoNDRkZDRoNDBoaDRkNDBsMGgwbGQ0MGxkNGQ4MGRoMDhkNGRoNDRkNGg0ZDRoNGRkODBoZDQ4ZDBoaDRkNDBsZDQwbDBkaDRoMDRkOGRkNGg0MGg0aDRkMGwwaDBsMGgwaGg0ZDQ0aDBkbDBoMGg0ZDRkOGQ0ZDhkNDAADNg0MDQwODQ0MDQwODQwNDQwNDQ0NDQwNphsMGgwaDQ0ZGg0NGRkOGQ0MGhoNGQ0NGgwaDBoaDA0aGgwZDg0ZGQ4NGQ0ZGg0MGgwbDBoNGgwaGQ4MGRoODBkNGRsMGgwNGhkNDRoNGRkOGQ0MGwwaGQ0aDQwaDRoMGgwbDBoMGg0ZDRoaDBoMDhkNGRoNGQ0aDRkNGg0ZDRkOGQ0MAAXc",
	"default": {
      "up": "sMDeAWibBgANDQ0NDQwNDQ4MDA0NDA4NDQwNDA0ODaYZDRoNGQ0MGxkNDBkbDBoNDRoYDRoNDRkNGg0ZGQ4MGhkOGQ0MGhoNDBoMGxkNDBsMGgwaDRkNGhoMDRkaDQ0ZDhkZDRoNDRkaDQ0ZDBsZDRkNDRoMGRsNDBkNGg0ZDRoNGQ0aDRkNGhkNGQ0aDQ0ZGg0ZDRoNGQ0ZDhkNGA8ZDQwZDgADNA0NDQ0NDA0NDQ0NDA0NDQ0MDQ0MDg0MpxkMGw0ZDA0aGgwNGhkNGQ0OGRkNGg0NGQ0aDBoaDQwaGQ4ZDQwaGg0MGg0aGQwNGg0ZDRoNGQ0aGQ0NGhkNDRkOGRkNGg0MGhoNDBoMGxkMGg0NGQ0ZGwwNGQ4ZDRkNGg0ZDRoNGQwbGQ0ZDRoNDBoaDRkNGg0ZDRkOGA0ZDxgNDRoNAAM0DgwNDQ0MDQ0NDQwNDA4NDA0NDA0ODA2mGgwbDBkNDRoZDQ0aGQ0ZDg0ZGQ0aDQwaDRoMGhoNDBkaDhkNDBoZDQ0ZDhkZDQ4ZDRkNGg0ZDRoZDQwbGQ0MGwwaGQ0aDQwZGwwNGQ0aGgwaDQ0ZDRoZDQ0ZDRoNGQ0aDBoMGwwaDBoaDBoNGgwNGRsMGgwaDRkNGg0ZDRoNGQ0MGwwABdw=",
      "down": "sMDeAWibBgAODQwNDgwNDA0NDA4NDA0NDA4NDA0NDKcaDBoMGg4MGhkNDRoZDBsNDBoZDRkNDRoNGQ0aGQ0NGRoNGQ0NGhkNDBsMGhkNDRkNGg0ZDRkOGRoMDRoZDQ0aDBoZDhkNDBoaDQwaDRoZDRoNDBoMGhoNDBoNGQ0ZDhkNGQ4ZDRkaDQ0ZGQ4ZDQ0aGQ0ZDRoMGg0aDRkMGw0MGRkODQADNA4MDQ0NDA0NDQ0MDQ0NDQwNDQ0MDgwNpxkMGw0ZDQwaGgwNGhkNGQ0OGRkNGg0NGQ0aDBoZDgwaGQ0aDQwaGg0MGQ0aGgwNGg0ZDRoNGQ0ZGg0NGRoNDBoNGhkNGQ4MGhkNDRoMGhoNGQwNGg0ZGwwNGQ0aDRkNGQ4ZDRkNGhkNDBsZDRkODBoZDRoNGQwaDRkOGQ4YDgsbGQ0NAAM1DQwNDg0MDQwNDA4NDQwNDA4NDA0NDA2mGwwaDBsMDRkaDQ0ZGQ4ZDQ0ZGg0ZDQ0aDBoMGxkNDBsZDRkODBkZDg0ZDRkaDQ0ZDRoNGQ0aDRkZDQ4ZGQ0NGgwaGg0ZDQwbGQ0MGg0ZGgwbDA0ZDhkZDQ0aDRkNGgwaDBsMGgwaGg0MGhoMGgwNGhkNGQ4ZDRkOGQ0ZDRoNDBoaDQwABdw="
	}
  }
}

I cannot figure out what I am doing wrong. Any help is appreciated.

what can we do about these logs?

Logger: homeassistant.components.climate
Source: components/climate/__init__.py:370
integration: Climate (documentation, issues)
First occurred: 11:26:16 (9 occurrences)
Last logged: 11:26:16

Entity None (<class 'custom_components.smartir.climate.SmartIRClimate'>) does not set ClimateEntityFeature.TURN_OFF but implements the turn_off method. Please report it to the author of the 'smartir' custom integration
Entity None (<class 'custom_components.smartir.climate.SmartIRClimate'>) does not set ClimateEntityFeature.TURN_ON but implements the turn_on method. Please report it to the author of the 'smartir' custom integration
Entity None (<class 'custom_components.smartir.climate.SmartIRClimate'>) implements HVACMode(s): off, heat, cool, heat_cool, dry, fan_only and therefore implicitly supports the turn_on/turn_off methods without setting the proper ClimateEntityFeature. Please report it to the author of the 'smartir' custom integration
Entity None (<class 'custom_components.smartir.climate.SmartIRClimate'>) implements HVACMode(s): off, cool, heat, dry, heat_cool and therefore implicitly supports the turn_on/turn_off methods without setting the proper ClimateEntityFeature. Please report it to the author of the 'smartir' custom integration
Logger: homeassistant.components.climate.const
Source: helpers/deprecation.py:197
integration: Climate (documentation, issues)
First occurred: 11:26:13 (9 occurrences)
Last logged: 11:26:13

HVAC_MODE_FAN_ONLY was used from smartir, this is a deprecated constant which will be removed in HA Core 2025.1. Use HVACMode.FAN_ONLY instead, please report it to the author of the 'smartir' custom integration
HVAC_MODE_AUTO was used from smartir, this is a deprecated constant which will be removed in HA Core 2025.1. Use HVACMode.AUTO instead, please report it to the author of the 'smartir' custom integration
SUPPORT_TARGET_TEMPERATURE was used from smartir, this is a deprecated constant which will be removed in HA Core 2025.1. Use ClimateEntityFeature.TARGET_TEMPERATURE instead, please report it to the author of the 'smartir' custom integration
SUPPORT_FAN_MODE was used from smartir, this is a deprecated constant which will be removed in HA Core 2025.1. Use ClimateEntityFeature.FAN_MODE instead, please report it to the author of the 'smartir' custom integration
SUPPORT_SWING_MODE was used from smartir, this is a deprecated constant which will be removed in HA Core 2025.1. Use ClimateEntityFeature.SWING_MODE instead, please report it to the author of the 'smartir' custom integration

Hi all. Just purchased a couple of Broadcom RM3 minis and none of my devices seem to be supported out of the box. Is there no way of learning via the Broadcom and then converting to the JSON? Or any tools to support doing it more quickly? I saw some posts about broad link manager for learning commands and another website that seemed to suggest it would convert, but unclear to me if they do what I think they do in helping create the JSON?

Thanks

You can try my mantained repo, which shall have all of these sorted a long ago… :wink:

3 Likes

Hello Borat! Do you mean Broadlink RM3? If so you can follow this guide to setup and learn commands on broadlink devices https://www.youtube.com/watch?v=jEOyTGaKwaQ&ab_channel=EverythingSmartHome

Your mantained repo has been a lifesaver, i was having constant crashing due to deprecated async calls in smartir original repo, now its working fine! thank you!

1 Like

Hi, yes i do, but it’s the conversion to SmartIR config that I was struggling with, as format seems to be different to what is captured by the learning process? I think copying an existing file and changing the codes is probably the best option but if there is a quicker way to convert the existing file, please let me know.

Thanks

So I’ve been trying to make this work and I managed to get the Off working, but I am a little confused by the smartir JSON structure and how to learn the commands and place them, based on the Broadcom JSON. I have a Samsung AC and it has heat, cool, dry and fan. When I look at the other files, they seem to have a different remote code for each termperature per mode. I’ve tried leaning by setting the temp in that mode clicking up on the remote, or setting the temp and then changing the mode on the remote. It learns something, and I can send the command via developer tools, but I cant via the climate device I created (eg if I set auto with temp 18 mapped as per the captured command, nothing happens). Can anyone give me some advice on how you went through the process of learning and mapping to the modes in the file pls? For info here is the top of my file. I used another as the basis to ensure structure is right and the Off command works fine, so something is wrong with the way I am mapping the other learned commands I think?

{
“manufacturer”: “Samsung”,
“supportedModels”: [
“Unknown”
],
“supportedController”: “Broadlink”,
“commandsEncoding”: “Base64”,
“minTemperature”: 17.0,
“maxTemperature”: 30.0,
“precision”: 1.0,
“operationModes”: [
“heat”,
“cool”,
“dry”,
“fan_only”
],
“fanModes”: [
“low”,
“med”,
“high”,
“auto”
],
“commands”: {
“off”: “JgDKAIyOFDITEBM0EzMTEBMQEzMTERIREzMTEBMQEzMTNBMQEzMTEBMzEzQTMxMzExATNBMzEzMUDxMQExESERI0FA8TEBMzFDMTMxQPExETEBIREhETEBMQExAUMhQzEzMUMhQyFKiSjRQzExAUMhQyFA8UEBMzFA4VDxQyFBATEBQyFDIUDxQzFA4VMhQyFDMUMhQPFDIUMxMzFA8UDxQPFA8UMxMQFA8UMhQzEzMUDxQPFA8TERMQEw8VDxQPFDITNBMzFDITMxMADQU=”,
“heat”: {
“low”: {
“17”: “JgDKAIyNFDMTEBMzEzMUDxQQEzMTEBMQEzMTEBQPFDMTMxMQEzMTMxQQEzMTMxMzEzMUMxMzExATMxQPFBATEBMQExATEBMQExATEBQPFDMTMxMQExATMxQyFDMTMxMQExATMxQzE6iRjhMzFBATMxMzExATEBMzFBATEBMzExATEBMzFDIUEBMzEzMTEBMzFDMTMxMzEzMUMxMQEzMTEBMQExAUDxQQExATEBMQExATEBMzEzMUEBMQEzMTMxMzFDMTEBMQEzMTMxQADQU=”,
“18”: “JgDCABMzExATEBMzExAUEBMzExATEBMzEzMUEBMzEzMTEBMzEzMUMxMzEzMTMxQQEzMTEBMQExATEBMQFA8UEBQPExATMxMzEzMUEBMQEzMTMxMzFA8UEBMQEzMTMxOpkY0UMxMQEzMTMxQQExATMxMQExATMxMQFBATMxMzExATMxQyFBATMxMzEzMUMxMzEzMTEBMzFA8UEBMQExATEBMQExATEBMQFDMTMxMzExATEBMzFDMTMxMQExATEBMzFDMTAA0F”,
“19”: “JgDKAIuOFDIUEBMzEzMTEBMQFDIUEBMQEzMTEBMQEzMUMxMQEzMTNBIQFDMTMxMzEzMUMxMzExATMxMQFA8UEBMQExATEBMQExATMxMzFDMTMxMQExATMxQzExATEBMQExATMxQyFKiRjhMzExAUMxMzExATEBMzFA8UDxQzExATEBMzEzMUEBMzEzMTEBMzFDIUMxMzEzMTMxQQEzMTEBMQExATEBMQFA8UEBMQEzMTMxMzFDMTEBMQEzMTMxQPFBATEBMQEzMTMxMADQU=”,
“20”: “JgDyABMAAk1jAAEmERAQMRAREBEQEBAREBEQEBAREDIQEQ8SDzIOExAQEDIQMRAxETEQMRAREBEQEBASDxEQEQ8SEBAQERAREBAREBAREBEQEBAREBEQEBEQEBEQEBEREBEPERAREBEPERAREBEQEBEQEBEQMRAxETEQMRFiYgABJhExEBEQERAQEBEQERAQERAQERAxEBEQERAxEBEQMg8yEBEQMRAxETEQMRExEDEQMRIwEBAREQ8REDIQMRAyEBAREBAREBAREBEQEBEQMRARETEPEg8yEBEPERAREDEQERAREBAREBAREDEQMRExEDERAA0FAAAAAAAA”,
“21”: “JgDyABQAAkxjAAEmEg8RMBIPERAQERAQERARERAPETEQERAREDEQEREQETARMBIwETARMBIQDxEREBEQEBEQEBAREBERDxIPEBERDxIPERAQEREPERAREBAREBEQERAQEBEQERAQEBEREBEPERAREBEPEg8RMBIwETAQMhFhYwABJhAyEBAREBAREQ8SDxEQEQ8SDxExEBAREBEREBAQMRAyEBEQMRAxETEQMREwEjARMBAyERAPEhAQDzMQMRAxERAQERAQEg8QERAxERAQMREQEDIQERAxEBEQERAQETEQEBEQERARDxEQETASMBAyEDESAA0FAAAAAAAA”,
“22”: “JgDyABQAAkxkAAElEg8RMBIPERAREBEPEg8REBEPEjAREBEQDjMQERAREDERMBIwETARMBIPERAREBEQEBEQEBAREBEQERAQERAREBEPERAREBEPEg8REBEPEg8REBEQERAQERAQEBEQERAQERAREBEPEg8RMBIwETARMRBiYgABJxExEBAQERAREBAREBEQERARDxExEQ8REBEQEQ8SMRAxEBEQMRAxEDIRMBEwEjARMBEwEg8RERAQETEQMRAxERAREBEQEQ8REBEQETARMBIPETASEBAxEBEQERAQEDIRDxIPERARDxIPETASMBEwETERAA0FAAAAAAAA”,
“23”: “JgDyABMAAk5iAAEmEREPMhARDxEQERAREBAREBAREDEQERAREDEQERAQETEQMhAxEDERMREQEBAREBAREBAREBAREQ8REBAREBEQEQ8SEBAQERAREBAREBEQEBAREBAREBAREBAREBEQEBEQEBIPERAREBEPMhAxEDIRMBBjYQABJxEwERAQERAQEREPEg8REBEQEQ8yEBEQEBExEDEQERAxEBEQMRAzDzIPMhAxEDIQMRAyEBAREBARETAQMRExEBEQEQ8SEBAQERAxETEQMREQEDEQERAxEBEQERAREDEQERAREBEPERAREDERMRAxEDERAA0FAAAAAAAA”,
“24”: “JgDyABMAAk5iAAEnEBAQMhAQEBEQERAQERAQERAREDEQERAQETEQEBERDzIQMg8yEDERMRAQERAQERAQERAQERAQERAQEg8REBEPEhAQDxIQERAQERAQERAREBAQERAREBAREBAREBAREBASDxEQERARDxEQMhAxETARMRBiYgABJxEwEBEQEBERDxIPERAREBEQEBAyEBAREBAxERAQMRExEBEQMRAxETIPMhAxEDIQMRAxERAREBAQETEQMRAyEBEPEhAQEBEQERAQERAQERAxEDEREBAyEBAREBASDzIPEg8REBEQERAQEDIQMRAxETEQAA0FAAAAAAAA”,
“25”: “JgDyABMAAk1iAAEnEBEQMRAREBEQEBEQERAQEBIPEDESDxARETAQERARETEPMhAxETERMBAREBAREBAREBERDxEQEBIPERARDhIQERAREBEQEBEQERAQEBEQEBERDxEQEBEQEBEQEBIPERARDhMPERAREBEQMREwEjARMBBjYgABJhEwEREPEhAQERAOExAQEBEQERAxERAREBEPERAQMRExEBARMRAyEDEQMhAxETASMBEwERAQEBIPETASMQ8yEBEQEBAREBEQERAxERARDxExETAREBEwEBEQEREQDzIQERAREBAREBEQEDERMBIwETARAA0FAAAAAAAA”,
“26”: “JgDyABUAAkxiAAEnEQ8RMRAQERAQERAQERAQERASDzIPERARDzIQERAREDEQMhAxEDERMREPEREPEg8REBEQEQ8REBEQERAQERAQERAQERAQERAQERAQEREQEBAQEg8REBEQERAQEBEQERAREBAQERAREQ8RMRAxEDERMRFhYwABJhAyEBEQEBAREBEQEBEQEBEQEBExEBAREBEQEBEQMg8yEBEPMhAxETEQMRAxETEQMRExEBEQEQ8SDzIQMRAyEQ8REBAREBAREBEQEDEQERAxEDIREA8yEBEQERAQETEQERAQEBEQERAQETEQMRAxETIQAA0FAAAAAAAA”,
“27”: “JgDyABQAAkxiAAEmEg8RMRAQEREQEBEQDhMQEQ8REDIRDxEQEDESDxEQEDEQMRIwETARMRAREBEQEBEQEBERDxEQERAREBEPERAQEREPERAREQ8REBEPEg8REBEQERAQERAREBAQERAREBAQEg8REBEPEg8QMhAyEDEQMRJgZAABJRIwEQ8SDxEQEQ8SDxEQERARDxExEBEQERAxEDEREBExEQ8RMREwETASMBEwETERMRAxEBEQEBIPEDESMBEwERAREBEPERARERAxDzIQERAxEDIRDxIwEQ8SDxARETAREBEPEhAQEBEQETEQMRAxEjARAA0FAAAAAAAA”,
“28”: “JgDyABQAAk1iAAEmERARMBEQERAREBARDhIQERAREDEREBEPETERDxIPETASMBEwETERMRAQEBEQERAQEg8REBAREQ8QERAREBAREBAREBAREQ8REBEQERARDxEQERAREBAREBEQEQ8REBEQEQ8SDxARERARMRAxEDEQMhFhYwABJhEwERAQERAQEBEREBEPERAQERAyDxIPERAREBEPMhAxERAQMRExEDEQMRIwETAQMhAyEBAQERAREDEQMRExEBEQEBEQEBEQERARDxIPMhAxEDIQEBExEBAREBAREDEQERAQERAQEg8REDIQMRAxETEQAA0FAAAAAAAA”,
“29”: “JgDyABQAAk1iAAEnEBEPMhAREBEQEBEQERARDxEQETAREBARETAREBEQETEQMRAxEDIQMREQEQ8SDxEQEQ8SDxEQERAREBAREBAREBAREBEPERAREBERDxEQERARDxEQERAQEBEQEBERDxIQEBEPERAREBEQMRAxEjAQMRFiYgABJhEwEg8REBEQERAPEg8REBEQERAxEBEREBEwEDEREBEwERARMBEyEDEQMRAyEDERMBIwEQ8REBEQETARMREwEBEQERAREBAQERAyEQ8RMREwEDESDxEwEg8REQ8RETEOEhAREBEQEBEQETASMBEwETARAA0FAAAAAAAA”,
“30”: “JgDyABQAAk1jAAElERAQMREQEBIPERARDxIQEBAREDEREBAREDEQERAQETEQMRAyEDEQMhAREBAQERAREBERDxEQERAQEBEQEBEQEBEQEBERDxERDxIPERAREBEQEBAREBERDxEQEBEQEBEQEBEQERAQERAQMRExEDIQMRBiYwABJhEwERAQERAREBAREBAREBAREBAxEREPEg8yEDEQERAxERAQMRExEDEQMRExEDIQMQ8zEBAREBAREDEQMhAxEBEQEBEQEBEQERAQEDIQMg8yEDEREBAxERAQERAQETEQERAQEBIPEg8RDzIQMhAxEDIQAA0FAAAAAAAA”
},

How can I set a target temperature? I want to keep the temperature between 20-22°C. I want the AC unit to turn off when the temperature exceeds 22°C and turn on when it drops below 20°C.

That’s done by the thermostat entity that you create.

Hi everyone,
I have a BIG problem with smartIR. I will try to summarize it with an example::

  1. The TV volume is currently at 10;
  2. If I send the command:
      action: remote.send_command
      target:
        device_id:
          - 2c5b55f8b1b624d637b25423a082b154
      data:
        device: tcl_tv
        command: volume_plus
        hold_secs: 0.1
  1. The volume increases until it reaches the value 23, therefore with an increase of 13 steps.

This, unfortunately, happens with all commands.
So if, for example, I want to change the video source, the relevant menu appears and disappears…

Nothing changes by trying various combinations of the command options:

      num_repeats: ...
      delay_secs: ...
      hold_secs: ...

Has anyone found a way to solve this annoying problem?
Thanks in advance to anyone who can give me support

Home your carrier duty percentage is correctly set. This is directly from esphome example.

remote_transmitter:
  pin: GPIOXX
  carrier_duty_percent: 50%

Ok, I’ll answer myself since I found the solution and I think it could help someone, so:
When learning the commands you only have to press the remote control buttons for a short moment.

In fact, if you hold down the button on the remote control, then the repeated pulsed emissions of the infrared diode are memorized and…
when you send the learned command it will be sent as it was learned (several times in pulses).

Hi guys, what should I do (if it’s possible) to add to my json a button to change the rotation of the fan?

{
    "manufacturer": "Lucci Air",
    "supportedModels": [
        "Whitehaven DC"
    ],
    "supportedController": "Broadlink",
    "commandsEncoding": "Base64",
    "speed": [
        "velocità 1",
        "velocità 2",
        "velocità 3",
        "velocità 4"
    ],
    "commands": {
        "off": "JgBQAAABHZESExITEjcSEhISExMSEhITEzYSNxISEjcSNxM2EzYSNxISEhQSEhISEhQSNhMSEhMSNxI3EjYSNxI3EhMSNxI3EgAE4gABHkgRAA0F",
        "default": {
            "velocità 1": "JgBQAAABHZATExISEjcSExITEhMTERMSEjcTNhITEjYSNxI3EjYTNhM3EhISNxITEjcSNxISEhMTEhI3EhMSNxISEhITNhM3EgAE4gABHkgRAA0F",
            "velocità 2": "JgBQAAABHZISEhISEjcSExMSEhMSEhMTEjcSNhITEjYTNhI3EjcTNRMTEjYTEhITEhITNhIUEhISNxITEjcSNhM2EhITNhI3EgAE4wABHUgRAA0F",
            "velocità 3": "JgBQAAABHZISEhITEzYSEhMTEhISExITEjcSNhITEjcTNhI3EjYTNhITEjYSNxITEzYSNxISEhMTNhITEhMSNxISEhMTNhI3EgAE4gABHUkRAA0F",
            "velocità 4": "JgBQAAABHZESEhITEjYTExISEhMTEhITEjcSNxISEjcSNhM2EjgSNxI2EjcSEhIUEhISNxITEhITEhITEjcSNxI2EhQSNhM2EgAE4gABHkgRAA0F"
        }
    }
}

Thanks!