Skip to content

Instantly share code, notes, and snippets.

@jrkoiter
Last active March 3, 2019 13:30
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jrkoiter/037acacc58a96753b2cc79dc7446a370 to your computer and use it in GitHub Desktop.
Save jrkoiter/037acacc58a96753b2cc79dc7446a370 to your computer and use it in GitHub Desktop.
#!/home/joost/homeassistant/bin/python3
# This script will make sure that no entity in your openzwave config cache file has a duplicate name.
# It will also create a backup of the file.
import xml.etree.ElementTree as ET
import copy
import re
import time
from shutil import copyfile
# Fill this dict with the unique name of your choice for each node id in your zwave network
node_names = {
"1": "Zwave Stick",
"2": "Fibaro Wall Plug 1",
"3": "Fibaro Wall Plug 2",
"4": "..."
}
# Enter correct path to zwcfg file here
zwcfg_file = '/home/joost/.homeassistant/zwcfg_0xxxxxxx.xml'
namespace = 'http://code.google.com/p/open-zwave/'
ET.register_namespace('', namespace)
tree = ET.parse(zwcfg_file)
def select_elements_with_same_label (haystack, needle):
elems = []
for i in range(len(haystack)):
h = haystack[i]
if h.attrib['label'] == needle.attrib['label'] and h is not needle:
elems.append(h)
return elems
def get_element_desc(elem):
return 'label: '+elem.attrib['label']+' instance: '+elem.attrib['instance']+' index: '+elem.attrib['index']
total_dup_count = 0
node_rename_count = 0
# Iterate config of all Zwave nodes
for node in tree.findall('./{'+namespace+'}Node'):
node_id = node.attrib['id']
node_name = node.attrib.get('name', '')
print("Handling node " + node.attrib['id'] + " (" + node_name + ")")
if(node_id in node_names and node_names[node_id] != node_name):
print("Renaming node to: " + node_names[node_id])
node.attrib['name'] = node_names[node_id]
node_rename_count += 1
# Iterate all child elements in node having attributes 'instance', 'index' and 'label'
elems = node.findall('.//*[@instance][@index][@label]')
dup_count = 0
visited = []
for elem in elems:
if elem in visited:
continue
# find elements having same label
dups = select_elements_with_same_label(elems, elem)
if dups:
dups.append(elem)
dups.sort(key=lambda i: (i.attrib['instance'], i.attrib['index']))
for dup in dups[1:]:
new_label = dup.attrib['label'] + ' ' + dup.attrib['instance'] + '_' + dup.attrib['index']
print(' Renaming element <' + get_element_desc(dup) + '> to have label "' + new_label + '" (duplicate of <'+get_element_desc(dups[0])+'>)')
dup.attrib['label'] = new_label
dup_count += 1
# to avoid visiting these nodes again
visited.extend(dups)
print('Number of renames: ' + str(dup_count))
total_dup_count += dup_count
millis = int(round(time.time() * 1000))
copyfile(zwcfg_file, zwcfg_file + '.' + str(millis) + '.xml')
tree.write(zwcfg_file, xml_declaration=True, encoding="utf-8")
print("Finished having renamed "+ str(node_rename_count) + " nodes and relabeled " + str(total_dup_count) + " elements")
exit(0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment