Skip to content

Instantly share code, notes, and snippets.

@bmfurtado
Created August 3, 2020 01:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bmfurtado/06aa9f6f4ef512673000aa1d3de9bced to your computer and use it in GitHub Desktop.
Save bmfurtado/06aa9f6f4ef512673000aa1d3de9bced to your computer and use it in GitHub Desktop.
Map IR codes for smartir climate stuff
import base64
import broadlink
import click
import json
import pdb
def split_csv(ctx, param, value):
return [x.strip() for x in value.split(',')]
def generate_temps(min, max, step):
n = min
while n <= max:
yield n
n = n + step
def choose_broadlink():
print('Discovering broadlinks in network...')
devices = broadlink.discover(timeout=10)
choices = list(range(len(devices)))
for i, device in enumerate(devices):
print('{}: {} [{}]'.format(i, device.model, device.host[0]))
while True:
choice = click.prompt('Choose a broadlink device.', type=int)
if choice in list(range(len(devices))):
break
print('Invalid choice, options are {}.'.format(choices))
return devices[choice]
def learn_code(device, message):
device.enter_learning()
while not click.confirm(message, default=True):
device.enter_learning()
code = base64.b64encode(device.check_data()).decode()
print('Learned {}'.format(code))
return code
def format_float(x):
return ('%f' % x).rstrip('0').rstrip('.')
@click.command()
@click.option('--outfile', type=click.File('w'), required=True)
@click.option('--manufacturer', prompt=True)
@click.option('--models', callback=split_csv, prompt=True)
@click.option('--min-temp', prompt=True, type=click.FLOAT)
@click.option('--max-temp', prompt=True, type=click.FLOAT)
@click.option('--temp-precision', prompt=True, type=click.FLOAT)
@click.option('--modes', prompt=True, callback=split_csv)
@click.option('--fan-modes', prompt=True, callback=split_csv)
def generate(outfile, manufacturer, models, min_temp, max_temp, temp_precision, modes, fan_modes):
device = choose_broadlink()
device.auth()
codes = {
'manufacturer': manufacturer,
'supportedModels': models,
'supportedController': 'Broadlink',
'commandsEncoding': 'Base64',
'minTemperature': min_temp,
'maxTemperature': max_temp,
'precision': temp_precision,
'operationModes': modes,
'fanModes': fan_modes,
}
commands = {}
for mode in modes:
commands[mode] = {}
print('Starting collection of mode {}.'.format(mode))
first_fan_mode = True
for fan_mode in fan_modes:
print('Starting collection of fan mode {}.'.format(fan_mode))
if not first_fan_mode and click.confirm('Do you want to skip this mode?'):
commands[mode][fan_mode] = commands[mode][list(commands[mode].keys())[0]]
continue
first_fan_mode = False
commands[mode][fan_mode] = {}
if click.confirm('Does this mode support temperatures?', default=True):
for t in generate_temps(min_temp, max_temp, temp_precision):
temp = format_float(t)
commands[mode][fan_mode][temp] = learn_code(device, 'Send code for {}/{}/{} and press enter.'.format(mode, fan_mode, temp))
else:
code = learn_code(device, 'Send code for {}/{} and press enter.'.format(mode, fan_mode))
for t in generate_temps(min_temp, max_temp, temp_precision):
temp = format_float(t)
commands[mode][fan_mode][temp] = code
commands['off'] = learn_code(device, 'Send code for off and press enter.')
codes['commands'] = commands
json.dump(codes, outfile)
if __name__ == '__main__':
generate()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment