Broadlink e-control to yaml

recently i bought a broadlink device.
and then i started to connect my remotes to the app so that my wife can control everything.
off course i liked to connect it all to HA as well.
i tried the broadlink learn command. it works but it isnt an easy way.
then i tried the part where you can import the codes from e-control into a txt file.
it bugged me that after that i needed to translate every code from hex to base 64.

so i changed the getBroadlinkSharedData.py a little.
now it also gives output from a yaml file like this:

    switches:
      kaarsen_aan:
        friendly_name: kaarsen aan
        command_on: 'JgDoAAABLZQTExQSExMUExMTExMTFBM2EzcTNxQ1FDYTNxQ1EzcUEhQTFDUUExMTEzcTExMTExMT
NxMTEzcTNxMTFDYUNRM3EwAFDwABLEkUAAxNAAEtSRMADE4AAStKFAAMTQABLEoTAAxOAAErShQA
DE0AASxJFQAMTQABLEkUAAxOAAErShMADE8AAStKEwAMTgABLUkSAAxPAAEsSRQADE4AAStKEwAM
TwABK0oTAAxPAAErShMADE0AAS5JEgAMTwABLEkVAAxNAAEsSRMADE8AAStKFAAMTgABLEkUAAxO
AAErShMADQU='
      kaarsen_uit:
        friendly_name: kaarsen uit
        command_on: 'JgDoAAABLZQTExMTExQTExMTExMTFBM2EzcTNxM3EzYTNxM3EzcTExMTEzcUEhM3EzcTExMTExQT
NhMUEzYTFBMTEzcTNhM3EwAFEQABLUoTAAxVAAEuSRMADFUAAS1KEwAMVQABLEkTAAxVAAEsShMA
DFUAASxJFAAMVAABLEoTAAxVAAEtShMADFQAAS5KEwAMVAABLkkUAAxUAAEtShMADFQAAS1KEwAM
VAABLUkTAAxVAAEtSRMADFUAASxKEwAMVAABLUkUAAxUAAEsShMADFUAAS1JEwAMVQABLEoTAAxU
AAEtShMADQU='
      kaarsen_Mode:
        friendly_name: kaarsen Mode
        command_on: 'JgCgAAABL5QUExMTExMUExQSExQTExM3EzcTNxQ2EzcTNxM2FDYTFBMTEzcTNxM3FDYTExMTFBMT
NxQSExQTExMUEzYUNhM3EwAFEQABLkoTAAxUAAEuShMADFQAAS5KEwAMVAABLkoUAAxUAAEuShMA
DFQAAS1KEwAMVAABLUoTAAxUAAEuSRQADFQAAS5JEwAMVQABLkoUAAxTAAEvSRQADQUAAAAAAAAA
AA=='
      kaarsen_4h:
        friendly_name: kaarsen 4h
        command_on: 'JgCIAAABLpQTExMUExMTFBQSExMTFBM3EzYTNxM3EzcTNxM3EzYTFBM3ExMTExMUExMTExMUExMT
FBM2EzcTNxM3EzcTNhM3EwAFEQABLkoTAAxUAAEtSRMADFQAAS1KFAAMUwABLUkUAAxUAAEtShMA
DFQAAS5KEwAMVAABLUoTAAxUAAEsShMADQU='
      kaarsen_8h:
        friendly_name: kaarsen 8h
        command_on: 'JgCYAAABLZQTExMUExMTExMUExMTExM3EzcTNxM2EzcTNxM3EzcTExMTEzcTExMUExMTExMUExMT
NxMTEzcTNhQ2EzcTNxM3EwAFEQABLEoTAAxWAAEsShMADFUAASxKEwAMVgABK0oTAAxWAAEsShMA
DFUAASxKEwAMVgABLEkTAAxWAAEsShMADFYAASxKEwAMVgABLEkTAA0F'
      kaarsen_Multi_color:
        friendly_name: kaarsen Multi color
        command_on: 'JgCQAAABLpQUExMTExMTFBMTExQTExM3EzcTNhM3EzcTNxM3EzcTExQ2EzcTExMTFBMTExMUExMT
ExMUEzcTNhM3EzYVNhM3EwAFEQABLkoTAAxVAAEuShMADFUAAS5JEwAMVQABLkoTAAxVAAEuSBUA
DFUAAS5KFAAMVQABLUoTAAxWAAEuSRMADFYAAS1KFAANBQAAAAAAAAAA'
      kaarsen_rood:
        friendly_name: kaarsen rood
        command_on: 'JgCYAAABLZQUEhQTExMTFBMTExMTFBM2FDYTNxM3EzcTNxM2EzcTFBMTExMTNxMTFBMTExMUExMT
NxM3ExMTNxQ2EzcTNhM3EwAFEgABLkkTAAxVAAEuSRMADFUAAS5JEwAMVgABLEoTAAxWAAEsShMA
DFUAAS1KEwAMVgABLEoTAAxVAAEsShMADFYAASxKEwAMVQABLEoTAA0F'
      kaarsen_blauw:
        friendly_name: kaarsen blauw
        command_on: 'JgBYAAABLZQUExMTExQSFBMTExQTExQ2FDUTNxM3EzcTNxM2EzcTExMUEzYTNxMUEhQTExMTExQT
NhQTExMTNxM3EzYTNxM3EwAFEQABLUkTAAxWAAEsShMADQU='
      kaarsen_groen:
        friendly_name: kaarsen groen
        command_on: 'JgBgAAABLJQUExMTExMTFBMTExMTFBM3EjcTNxM3EzcTNhM3EzcTExM3FBMTNhMUExMTExMUExMT
ExM3FBMTNhM3FDYTNxQ2EwAFEQABLUoTAAxWAAEtShQADFUAAS1JEwANBQAAAAAAAAAA'
      kaarsen_blauw:
        friendly_name: kaarsen blauw
        command_on: 'JgB4AAABLZQUEhMTExQTExMTExQSFBM3EjcUNhM3EzYTNxM3EzcTExM3ExMTExM3ExMTExMUExMT
ExM3EzcTExM3EzYTNxM3EwAFEQABLEoTAAxUAAEsShQADFMAASxKEwAMVAABLEoTAAxUAAEsShMA
DFMAASxKEwANBQ=='
      kaarsen_bruin:
        friendly_name: kaarsen bruin
        command_on: 'JgCQAAABLZQTExMUExMTExMTExQTExM3EzcTNhM3EzcTNxM2EzcTExM3EzcTNxMTExMTExMUExMT
ExMUExMTNxM2EzcTNxM3EwAFEAABLEoTAAxTAAEtShMADFQAAS1JEwAMUwABLUoTAAxTAAEtShQA
DFQAAS1JEwAMUgABLUoTAAxSAAEsShMADFIAASxJEwANBQAAAAAAAAAA'
      kaarsen_groen:
        friendly_name: kaarsen groen
        command_on: 'JgB4AAABLpMUExMTExMTFBMTExMTFBM2EzcTNxM2FDYTNxM3EzcTExMTExQTExM3ExMTExQTExMT
NxM3EzYUExM2FDYTNxM3EwAFDwABLkkUAAxQAAEuSRMADFIAAS5KEwAMUQABLkoTAAxRAAEuShMA
DFEAASxKEwANBQ=='
      kaarsen_geel:
        friendly_name: kaarsen geel
        command_on: 'JgCQAAABLpMUExMTExMTFBMTExMTFBM2EzYUNxM2EzcTNxM2EzcTExMUEzYTFBM2FBMTExMTExMT
NxMTEzcTExM3EzcTNxM2EwAFEAABLUoTAAxTAAEuSRQADFIAAS5KEwAMUgABLUkUAAxPAAEuSRMA
DFAAAS1KEwAMTwABLUoTAAxQAAEtShMADFAAASxKEwANBQAAAAAAAAAA'
      kaarsen_paars:
        friendly_name: kaarsen paars
        command_on: 'JgCYAAABLJQTExMTExMUEhMUExMUEhM3EzYTNxQ2EjcUNhM2FDYTExMTEzcUNhI3ExMTFBMTExMT
NxQSExMTExM3EzcUNRM3EwAFDwABLEoTAAxPAAErShMADFAAAS1JEwAMUAABLUkTAAxQAAEsShMA
DE8AASxKEwAMTwABLUoTAAxPAAEuSRMADFAAAS1JFAAMUAABLkoTAA0F'
      kaarsen_roze:
        friendly_name: kaarsen roze
        command_on: 'JgCIAAABMJMTExQTExMTExMUExMTExQ2EzcTNhQ2EzcUNhM2EzcTExMUExMTNxM3ExMTExMUExMT
NxQ1FBMTExM3EzcTNhM3EwAFEAABLkoUAAxXAAEuSRMADFMAAS9KFAAMUAABLUoTAAxQAAEtShMA
DFAAAS5JEwAMUAABL0kTAAxTAAEtShQADQU='
      kaarsen_blauw:
        friendly_name: kaarsen blauw
        command_on: 'JgCgAAABLZMTExQTExMTFBMTExMTFBM2EzcUNhM3EzYTNxM3EzcUEhM3ExMTNxM3ExMTExQTFBIT
FBM2ExQTExM3EzYTNxM3EwAFDwABLEoTAAxRAAErShQADFMAAStKEwAMUgABLUoTAAxWAAEvShMA
DFMAAS5KEwAMUQABL0kTAAxQAAEuSRMADFYAAS9IEwAMVwABLkoTAAxQAAEtShQADQUAAAAAAAAA
AA=='
      kaarsen_blauw:
        friendly_name: kaarsen blauw
        command_on: 'JgCgAAABLZQTExMTExMTFBMTFBITFBI3EzcTNxM2EzcTNxM2FDYTExM3EzYTFBM2EzcTExMUExMT
ExMTEzcTExMTEzcTNxM2EwAFEQABLkgUAAxXAAEsShMADFwAAS1JEwAMXQABLEoTAAxUAAEuSBMA
DFsAAS1JFAAMWQABLEkTAAxVAAEtSRMADFUAAS1JEwAMUQABLEkTAAxWAAEtShQADQUAAAAAAAAA
AA=='
      kaarsen_roze:
        friendly_name: kaarsen roze
        command_on: 'JgCwAAABLpQTFBMTExQTExMTExQTExM3FDYTNhM3EzcTNxM2EzcTExM3EzcUNhM2FDYTFBMTExMT
FBMTExMUExQSEzcTNxM2EwAFFQABLUoTAAxZAAEuShQADFYAAS9JEwAMVQABLUkTAAxQAAEtSRQA
DFEAASxKEwAMUAABLUkTAAxUAAEuSRMADE8AAS1KEwAMUAABLUoTAAxPAAEsShQADE4AAS1JEwAM
UQABLUkTAA0FAAAAAAAAAAA='



group:
  kaarsen:
    name: kaarsen
    view: yes
    entities:
      - switch.kaarsen_aan
      - switch.kaarsen_uit
      - switch.kaarsen_Mode
      - switch.kaarsen_4h
      - switch.kaarsen_8h
      - switch.kaarsen_Multi_color
      - switch.kaarsen_rood
      - switch.kaarsen_blauw
      - switch.kaarsen_groen
      - switch.kaarsen_blauw
      - switch.kaarsen_bruin
      - switch.kaarsen_groen
      - switch.kaarsen_geel
      - switch.kaarsen_paars
      - switch.kaarsen_roze
      - switch.kaarsen_blauw
      - switch.kaarsen_blauw
      - switch.kaarsen_roze

after that all you need to do is check for duplicate names that are not used in HA and you can copy it to your yaml files.

the edited pycode:

# -*- coding: utf-8 -*-

'''
This script will "parse" the broadlink e-Control Android application "SharedData" json files and dump the IR / RF codes for selected accessories into a text file which can be later used with broadlink-python to send the codes to the RM PRO hub
NO ROOT ACCESS REQUIRED

Just connect your Android device to your computer and browse the SD card / External Storage folder "/broadlink/newremote/SharedData/"
You need to get the following files:

jsonSubIr
jsonButton
jsonIrCode

and put them in the same folder as this script.

run: python getBroadlinkSharedData.py

'''

import simplejson as json


buttonIDS = []
buttonNames = []


jsonSubIr = open("jsonSubIr").read()
jsonSubIrData = json.loads(jsonSubIr)


for i in range(0, len(jsonSubIrData)):
    print "ID:", jsonSubIrData[i]['id'], "| Name:", jsonSubIrData[i]['name']


choice = input("Select accessory ID: ")

for i in range(0, len(jsonSubIrData)):
    if jsonSubIrData[i]['id'] == choice:
        accessory_name = jsonSubIrData[i]['name']
        print "[+] You selected: ", accessory_name


jsonButton = open("jsonButton").read()
jsonButtonData = json.loads(jsonButton)


for i in range(0, len(jsonButtonData)):
    if jsonButtonData[i]['subIRId'] == choice:
        buttonIDS.append(jsonButtonData[i]['id'])
        buttonNames.append(jsonButtonData[i]['name'])


jsonIrCode = open("jsonIrCode").read()
jsonIrCodeData = json.loads(jsonIrCode)


print "[+] Dumping codes to " + accessory_name + ".txt"
print "[+] Dumping yaml to " + accessory_name + ".yaml"


codesFile = open(accessory_name + '.txt', 'w')
yamlFile = open(accessory_name + '.yaml', 'w')

groupstext = "\n\n\ngroup:\n"
groupstext = groupstext + "  " + accessory_name + ":\n"
groupstext = groupstext + "    name: " + accessory_name + "\n"
groupstext = groupstext + "    view: yes\n"
groupstext = groupstext + "    entities:\n"

yamltext = "    switches:\n"

for i in range(0, len(jsonIrCodeData)):
    for j in range(0, len(buttonIDS)):
        if jsonIrCodeData[i]['buttonId'] == buttonIDS[j]:
            code = ''.join('%02x' % (i & 0xff) for i in jsonIrCodeData[i]['code'])
            code_b64 = code.decode("hex").encode("base64")
            result = "Button Name: " + buttonNames[j] + " | Button ID: " + str(jsonIrCodeData[i]['buttonId']) + " | Code: " + code
            namepart = buttonNames[j].replace(" ","_")
            yamltext = yamltext + "      " + accessory_name + "_" + namepart + ":\n"
            yamltext = yamltext + "        friendly_name: " + accessory_name + " " + buttonNames[j] + "\n"
            yamltext = yamltext + "        command_on: '" + code_b64[:-1] + "'" + "\n"
            groupstext = groupstext + "      - switch." + accessory_name + "_" + namepart + "\n"
            codesFile.writelines(result.encode('utf-8'))
yamlFile.writelines(yamltext.encode('utf-8'))
yamlFile.writelines(groupstext.encode('utf-8'))

there is 1 requirement: you need to give the buttons in e-control a name to get names in the yaml.
off course you could set the names afterwards if you remember the order you have recorded the buttons :wink:

hope this helps others.

by the way, the yaml i did put here is from a set of remote candles with a small ir remote.
do have one like this? then you could use this file, just change the names to your wish.

edit: i also let it automaticly create a group fot the remote you import, so that you directly have all switches together in 1 group.

12 Likes

Many thanks ReneTode makes it much easier to instert into HA :smiley:

indeed.

the only thing i noticed afterwards: you can only set the buttonnames the right way if you chose custom remote.
the defaults dont have the option to edit the buttons.

but maybe we could create a list of broadlink remotes?

I pretty much always choose custom as there are never enuff buttons on the default options :stuck_out_tongue:

1 Like

how so i run the script?

python getBroalinkSharedData.py

if you have followed the instructions for broadlinkswitch you have a dir where you have a file called getBroadlinkSharedData.py
just save the file i created with the same name and run it like keith said.
so you need to have the e control files in the same directory.

Yes, i read it… but i dont know how to run PY script :slight_smile: i just google it.

Thanks Rene.

io get error what i miss?

C:\python\br>py getBroalinkSharedData.py
File “getBroalinkSharedData.py”, line 32
print “ID:”, jsonSubIrData[i][‘id’], “| Name:”, jsonSubIrData[i][‘name’]
^
SyntaxError: Missing parentheses in call to ‘print’

you probably tried to run it in python 3 and it is written for python 2.

so your command would be:

python2 getBroadlinkSharedData.py 

You’re missing a “d” :wink:

probably he saved it without the d also, because the code is running :wink:
i made a typo before :wink:

rewritten code for python 3 for those who prefer to use python 3 and not python 2

# -*- coding: utf-8 -*-

'''
This script will "parse" the broadlink e-Control Android application "SharedData" json files and dump the IR / RF codes for selected accessories into a text file which can be later used with broadlink-python to send the codes to the RM PRO hub
NO ROOT ACCESS REQUIRED

Just connect your Android device to your computer and browse the SD card / External Storage folder "/broadlink/newremote/SharedData/"
You need to get the following files:

jsonSubIr
jsonButton
jsonIrCode

and put them in the same folder as this script.

run: python getBroadlinkSharedData.py

'''

import simplejson as json
import codecs

buttonIDS = []
buttonNames = []


jsonSubIr = open("jsonSubIr").read()
jsonSubIrData = json.loads(jsonSubIr)


for i in range(0, len(jsonSubIrData)):
    print ("ID:", jsonSubIrData[i]['id'], "| Name:", jsonSubIrData[i]['name'])


choice = input("Select accessory ID: ")

accessory_name = jsonSubIrData[int(choice)-1]['name']
print ("[+] You selected: ", accessory_name)

jsonButton = open("jsonButton").read()
jsonButtonData = json.loads(jsonButton)


for i in range(0, len(jsonButtonData)):
    if str(jsonButtonData[i]['subIRId']) == str(choice):
        buttonIDS.append(jsonButtonData[i]['id'])
        buttonNames.append(jsonButtonData[i]['name'])

jsonIrCode = open("jsonIrCode").read()
jsonIrCodeData = json.loads(jsonIrCode)

print ("[+] Dumping HEX codes to " + accessory_name + ".txt")
print ("[+] Dumping yaml to " + accessory_name + ".yaml")


codesFile = open(accessory_name + '.txt', 'w')
yamlFile = open(accessory_name + '.yaml', 'w')

groupstext = "\n\n\ngroup:\n"
groupstext = groupstext + "  " + accessory_name + ":\n"
groupstext = groupstext + "    name: " + accessory_name + "\n"
groupstext = groupstext + "    view: yes\n"
groupstext = groupstext + "    entities:\n"

yamltext = "    switches:\n"

for i in range(0, len(jsonIrCodeData)):
    for j in range(0, len(buttonIDS)):
        if jsonIrCodeData[i]['buttonId'] == buttonIDS[j]:
            code = ''.join('%02x' % (i & 0xff) for i in jsonIrCodeData[i]['code'])
            code_b64 = codecs.encode(codecs.decode(code, 'hex'), 'base64').decode()
            result = "Button Name: " + str(buttonNames[j]) + " | Button ID: " + str(jsonIrCodeData[i]['buttonId']) + " | Code: " + str(code)
            namepart = buttonNames[j].replace(" ","_")
            yamltext = yamltext + "      " + accessory_name + "_" + namepart + ":\n"
            yamltext = yamltext + "        friendly_name: " + accessory_name + " " + buttonNames[j] + "\n"
            yamltext = yamltext + "        command_on: '" + str(code_b64[:-1]) + "'" + "\n"
            groupstext = groupstext + "      - switch." + accessory_name + "_" + namepart + "\n"
            codesFile.writelines(result)
yamlFile.writelines(yamltext)
yamlFile.writelines(groupstext)
1 Like

i just google it and install via pip now that working :slight_smile:

1 Like

I think you need to install simplejson, something like sudo apt-get install simplejson, you may want to google that as i’m doing this off the top of my head :slight_smile:

i just tried to add some more remotes.

some things to think about:

  1. dont use spaces in the names from the econtrol remote, or replace them in the yaml afterwards with _
  2. Capitals are somehow not allowed in the naming from the entities, so dont use them in econtrol either.
  3. if you delete remotes from econtrol, the python3 version will have trouble finding some remotes. python2 works fine.

if there is enough reason for it i will try to change the code some more to take these problems out, automaticly.

Work with pip install simplejson via Scripts folder :slight_smile:

How do i know what is the command to on / off tv?
i get like this

switches:
  Audio_:
    friendly_name: Audio 
    command_on: 'JgBOACETExMTMhMyExMTMhMTEzITExMyEzIUAAEpIRMTExMyEzITExMyExMTMhMTEzITMhQAASkh

ExMTEzITMhMTEzITExMyExMTMhMyFAAIBQ==’
Audio_:
friendly_name: Audio
command_on: ‘JgBOACETEyUTExMdEyUTExMTEyUTExMdEyUUAAEpIRMTJRMTEx0TJRMTExMTJRMTEx0TJRQAASkh
ExMlExMTHRMlExMTExMlExMTHRMlFAAIBQ==’

also what is worng here? im on this more then 1H Thanks!

in the picture you show a invalid yaml.

you need to look at your spaces.

switches (beneath mac) needs to have 2 spaces more then mac.
reciever needs needs 2 more
friendlyname needs 2 more then tv_phillips. (not 1)

so every time 2 more spaces.

Hi Rene,

I hope you don’t mind my very simple question, I have no programming experience at all. I have two Broadlink RM Pro which control 7 devices, both IR and RF. I want to use home assistant with Alexa to control them. Before I purchase a RP3+ I decided to try out HA on a windows 10 PC. I have installed python 3, simplejson and downloaded the eControl scripts. I have copied my shared data from the eControl app to the same folder and I have created the getBroadlinkSharedData.py for python 3. I ran the getBroadlinkSharedData.py i get a list of the remotes I have created and it asks me to select one. I select one of the ID’s and it appears to create a tXT and YAML file but none of them contain any code. Can you help me where I am going wrong?

C:\Users\julie\AppData\Roaming.homeassistant\Broadlink-e-control-db-dump-master>getBroadlinkSharedData.py
ID: 13 | Name: Soundbar
ID: 14 | Name: TV-lights
ID: 16 | Name: power-remote
ID: 19 | Name: TV
ID: 21 | Name: Android TV
ID: 22 | Name: Sky Q
ID: 23 | Name: An RF Switch
Select accessory ID: 4
[+] You selected: TV
[+] Dumping HEX codes to TV.txt
[+] Dumping yaml to TV.yaml

This is the YAML file I get

switches:

group:
TV:
name: TV
view: yes
entities:

The text file is empty.

Thank you

i havent used that code for a long time so i dont know what is wrong.
i see you selected ID 4 and the valid IDs shown are 13,14,16,19,21,22,23
but it selected TV on ID 19

so i am a bit puzzled.
at the moment i cant look at it, but please remind me tommorow and i will take a look what could be wrong.

Thanks,

I did wonder about the numbering, if I enter the listed number it doesn’t work. If i use 1 for the top one I get the empty files. I’ll clear the data on the broadlink app and try adding just one remote and see if I get index 1.

If I can’t sort it I’ll post back here tomorrow.

Paul