├── .gitignore ├── LICENSE ├── README.md └── generateId.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | .hypothesis/ 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | local_settings.py 55 | 56 | # Flask stuff: 57 | instance/ 58 | .webassets-cache 59 | 60 | # Scrapy stuff: 61 | .scrapy 62 | 63 | # Sphinx documentation 64 | docs/_build/ 65 | 66 | # PyBuilder 67 | target/ 68 | 69 | # IPython Notebook 70 | .ipynb_checkpoints 71 | 72 | # pyenv 73 | .python-version 74 | 75 | # celery beat schedule file 76 | celerybeat-schedule 77 | 78 | # dotenv 79 | .env 80 | 81 | # virtualenv 82 | venv/ 83 | ENV/ 84 | 85 | # Spyder project settings 86 | .spyderproject 87 | 88 | # Rope project settings 89 | .ropeproject 90 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) [year] [fullname] 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RFXcomIdGenerator 2 | 3 | Generate RFXcom IDs for Home Assistant 4 | 5 | As great as Home Assistant is, the RFXcom detection can be a little tricky. For example the remote that comes with the Energenie Wireless Sockets (4 pack) does not get picked up by the RFX. So when the docs say to set `automatic_add` to `True` and press the button on the remote, this doesn't do anything. Because the remote signal is not being received by RFX, there is no way it can be passed to Home Assistant. 6 | 7 | To get around this you have to create a new switch in Hass and then pair the device to the new switch as if it was a new remote control. Usually this involves pressing and holding a button on the recieving device untill it goes into pairing mode, then "turn on" the new switch using the Hass UI. 8 | 9 | This excellent script by [Sennevds](https://github.com/Sennevds) helps generate the the IDs required by Hass when adding the new switches. 10 | 11 | ## Usage 12 | 13 | `generateId.py -t type -s subtype -p parameters` 14 | 15 | e.g. 16 | 17 | to generate a code for a Lighting1 type device using ARC subtype, set to housecode A unit code 3 18 | 19 | `python generateId.py -t Lighting1 -s ARC -p A,3` 20 | 21 | ### Supported types: 22 | 23 | - Lighting1 24 | - Lighting5 25 | 26 | ### Supported subtypes: 27 | 28 | - X10 29 | - AC 30 | - LightwaveRF 31 | - ARC 32 | - HomeEasy EU 33 | - EMW100 34 | - AB400D 35 | - ANSLUT 36 | - BBSB 37 | - Waveman 38 | - MDREMOTE 39 | - EMW200 40 | - Conrad RSL2 41 | - IMPULS 42 | - Livolo 43 | - RisingSun 44 | - RGB TRC02 45 | - Philips SBC 46 | - Energenie 47 | - GDR2 48 | - ProMax 49 | - IT 50 | 51 | 52 | ### Parameters are a comma separated list (no spaced) depending on type: 53 | 54 | Lighting1: housecode,unitID 55 | 56 | e.g. `-p A,3` or `-p A,1` 57 | 58 | Lighting5: id,unit_code 59 | 60 | ## For more details 61 | 62 | https://community.home-assistant.io/t/how-to-define-id-for-rfxcom-s-component/7788 63 | -------------------------------------------------------------------------------- /generateId.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | 4 | TYPES = {'X10': '00', 5 | 'AC': '00', 6 | 'LightwaveRF': '00', 7 | 'ARC': '01', 8 | 'HomeEasy EU': '01', 9 | 'EMW100': '01', 10 | 'AB400D': '02', 11 | 'ANSLUT': '02', 12 | 'BBSB': '02', 13 | 'Waveman': '03', 14 | 'MDREMOTE': '03', 15 | 'EMW200': '04', 16 | 'Conrad RSL2': '04', 17 | 'IMPULS': '05', 18 | 'Livolo': '05', 19 | 'RisingSun': '06', 20 | 'RGB TRC02': '06', 21 | 'Philips SBC': '07', 22 | 'Energenie': '08', 23 | 'Energenie5': '09', 24 | 'GDR2': '0a', 25 | 'ProMax': '0f', 26 | 'IT': '0f' } 27 | 28 | HOUSECODES = { 29 | 'A': '41', 30 | 'B': '42', 31 | 'C': '43', 32 | 'D': '44', 33 | 'E': '45', 34 | 'F': '46', 35 | 'G': '47', 36 | 'H': '48', 37 | 'I': '49', 38 | 'J': '4A', 39 | 'K': '4B', 40 | 'L': '4C', 41 | 'M': '4D', 42 | 'N': '4E', 43 | 'O': '4F', 44 | 'P': '50'} 45 | 46 | def generate_id(type, subType, args): 47 | if type == 'Lighting1': 48 | if len(args) == 2: 49 | Lighting1(subType, args) 50 | else: 51 | print ('Wrong arguments') 52 | 53 | elif type == 'Lighting2': 54 | Lighting2(subType, args) 55 | elif type == 'Lighting3': 56 | id = '812' 57 | elif type == 'Lighting4': 58 | id = '913' 59 | elif type == 'Lighting5': 60 | if len(args) == 2: 61 | Lighting5(subType, args) 62 | else: 63 | print ('Wrong arguments') 64 | elif type == 'Lighting6': 65 | id = '0b15' 66 | 67 | 68 | def Lighting1(subType, args): 69 | id = '0710' + TYPES[subType] + '00' + HOUSECODES[args[0]] + '0' + format(int(args[1]), 'x').upper() + '00' + '00' 70 | print (id) 71 | 72 | def Lighting2(subType, args): 73 | id = '0b11' 74 | 75 | def Lighting5(subType, args): 76 | id_combined = int(args[0]) 77 | id1 = id_combined >> 16 78 | id2 = id_combined >> 8 & 0xff 79 | id3 = id_combined & 0xff 80 | id = '0a14' + TYPES[subType] + '00' + str(id1) + str(id2) + str(id3) + args[1] + '00' + '00' 81 | print (id) 82 | 83 | 84 | #generate_id('Lighting5','Livolo',['2827','4']) 85 | 86 | import sys, getopt 87 | 88 | def main(argv): 89 | type = '' 90 | subtype = '' 91 | params = '' 92 | try: 93 | opts, args = getopt.getopt(argv,"ht:s:p:",["type=","subtype=", "params="]) 94 | except getopt.GetoptError: 95 | print ('generateId.py -t -s -p ') 96 | sys.exit(2) 97 | for opt, arg in opts: 98 | if opt == '-h': 99 | print ('generateId.py -t -s -p ') 100 | sys.exit() 101 | elif opt in ("-t", "--type"): 102 | type = arg 103 | elif opt in ("-s", "--subtype"): 104 | subtype = arg 105 | elif opt in ("-p", "--params"): 106 | params = arg 107 | list = params.split(",") 108 | 109 | generate_id(type,subtype, list) 110 | 111 | if __name__ == "__main__": 112 | main(sys.argv[1:]) 113 | --------------------------------------------------------------------------------