1#!/bin/python 2 3import re 4import sys 5 6from anytree import Node, RenderTree 7 8usage = """ 9Usage: using local file or stdin to parse i2c bus info to tree 10 1. ssh user@<ip> "i2cdetect -l" > i2c_bus_info.txt 11 2. python tree.py i2c_bus_info.txt 12 13 or 14 15 ssh user@<ip> "i2cdetect -l" | python tree.py 16""" 17 18node_dict = {} 19root = Node("root") 20 21 22def parse_line(line): 23 line = line.strip() 24 regex = re.compile(r"(i2c-\d+)\s+i2c\s+(.*)\s+I2C adapter") 25 m = regex.match(line) 26 if m: 27 bus = m.group(1) 28 name = m.group(2).strip() 29 return (bus, name) 30 else: 31 return None 32 33 34def draw(line): 35 i2c = parse_line(line) 36 if not i2c: 37 return 38 39 bus, name = i2c 40 41 if "mux" not in name: 42 node_dict[bus] = Node(bus, parent=root) 43 else: 44 mux_regex = re.compile(r"i2c-(\d+)-mux \(chan_id (\d+)\)") 45 m = mux_regex.match(name) 46 if m: 47 i2c = m.group(1) 48 if "i2c-" + i2c in node_dict: 49 node_dict[bus] = Node(bus, parent=node_dict["i2c-" + i2c]) 50 51 52def parse_from_file(file): 53 with open(file, "r") as f: 54 lines = f.readlines() 55 for line in lines: 56 draw(line) 57 58 59def parse_from_stdin(): 60 lines = sys.stdin.readlines() 61 for line in lines: 62 draw(line) 63 64 65def print_tree(): 66 for pre, fill, node in RenderTree(root): 67 print("%s%s" % (pre, node.name)) 68 69 70if __name__ == "__main__": 71 if len(sys.argv) == 2: 72 if ( 73 sys.argv[1] == "-h" 74 or sys.argv[1] == "--help" 75 or sys.argv[1] == "help" 76 or sys.argv[1] == "?" 77 ): 78 print(usage) 79 sys.exit(0) 80 81 try: 82 if len(sys.argv) == 2: 83 file = sys.argv[1] 84 parse_from_file(file) 85 else: 86 parse_from_stdin() 87 except Exception as e: 88 print(e) 89 print(usage) 90 sys.exit(1) 91 92 print_tree() 93