9 import termios, fcntl, os
14 from dbus.mainloop.glib import DBusGMainLoop
31 def __init__(self, n, d):
40 self.commands.append(Autocomplete.Cmd('help', 'Prints help data (also see COMMAND help)'))
41 self.commands.append(Autocomplete.Cmd('list', 'List supported ObjectNames'))
42 self.commands.append(Autocomplete.Cmd('get', 'Get properties from an ObjectName'))
43 self.commands.append(Autocomplete.Cmd('listen', 'Listen for changes on an ObjectName'))
44 self.commands.append(Autocomplete.Cmd('set', 'Set a property for an ObjectName'))
45 self.commands.append(Autocomplete.Cmd('getHistory', 'Get logged data within a time range'))
46 self.commands.append(Autocomplete.Cmd('plugin', 'enable, disable and get info on a plugin'))
47 self.commands.append(Autocomplete.Cmd('quit', 'Exit ambctl'))
49 bus = dbus.SystemBus()
51 managerObject = bus.get_object("org.automotive.message.broker", "/");
52 managerInterface = dbus.Interface(managerObject, "org.automotive.Manager")
53 self.properties = managerInterface.List()
54 except dbus.exceptions.DBusException, error:
57 def complete(self, partialString, commandsOnly = False):
62 for cmd in self.commands:
63 if not (len(partialString)) or cmd.name.startswith(partialString):
64 results.append(cmd.name)
67 for property in self.properties:
68 if not(len(partialString)) or property.startswith(partialString):
69 results.append(str(property))
71 if len(results) > 1 and len(results[0]) > 0:
72 for i in range(len(results[0])):
73 for j in range(len(results[0])-i+1):
74 if j > len(sameString) and all(results[0][i:i+j] in x for x in results):
75 sameString = results[0][i:i+j]
76 elif len(results) == 1:
77 sameString = results[0]
79 return results, sameString
83 help = ("Available commands:\n")
84 autocomplete = Autocomplete()
85 for cmd in autocomplete.commands:
86 help += bcolors.HEADER + cmd.name + bcolors.WHITE
87 for i in range(1, 15 - len(cmd.name)):
89 help += cmd.description + "\n"
93 def changed(interface, properties, invalidated):
94 print json.dumps(properties, indent=2)
98 for root, dirs, files in os.walk('@PLUGIN_SEGMENT_INSTALL_PATH@'):
100 fullpath = root + "/" + file;
101 pluginFile = open(fullpath)
102 data = json.load(pluginFile)
103 data['segmentPath'] = fullpath
108 def enablePlugin(pluginName, enabled):
112 if plugin["name"] == pluginName:
114 plugin["enabled"] = enabled
115 file = open(plugin["segmentPath"], 'rw+')
116 plugin.pop('segmentPath', None)
117 fixedData = json.dumps(plugin, separators=(', ', ' : '), indent=4)
118 fixedData = fixedData.replace(' ','\t');
120 file.write(fixedData)
123 except IOError, error:
129 def processCommand(command, commandArgs, noMain=True):
131 if command == 'help':
135 bus = dbus.SystemBus()
139 managerObject = bus.get_object("org.automotive.message.broker", "/");
140 managerInterface = dbus.Interface(managerObject, "org.automotive.Manager")
141 return managerInterface
143 print "Error connecting to AMB. is AMB running?"
146 if command == "list" :
147 managerInterface = getManager(bus)
148 supportedList = managerInterface.List()
149 for objectName in supportedList:
152 elif command == "get":
153 if len(commandArgs) == 0:
154 commandArgs = ['help']
155 if commandArgs[0] == "help":
156 print "ObjectName [ObjectName...]"
158 managerInterface = getManager(bus)
159 for objectName in commandArgs:
160 objects = managerInterface.FindObject(objectName)
163 propertiesInterface = dbus.Interface(bus.get_object("org.automotive.message.broker", o),"org.freedesktop.DBus.Properties")
164 print json.dumps(propertiesInterface.GetAll("org.automotive."+objectName), indent=2)
166 elif command == "listen":
168 if len(commandArgs) == 0:
169 commandArgs = ['help']
170 if commandArgs[0] == "help":
171 print "[help] [off] ObjectName [ObjectName...]"
173 elif commandArgs[0] == "off":
175 commandArgs=commandArgs[1:]
176 managerInterface = getManager(bus)
177 for objectName in commandArgs:
178 objects = managerInterface.FindObject(objectName)
181 signalMatch = bus.add_signal_receiver(changed, dbus_interface="org.freedesktop.DBus.Properties", signal_name="PropertiesChanged", path=o)
182 Subscribe.subscriptions[o] = signalMatch
185 signalMatch = Subscribe.subscriptions.get(o)
187 del Subscribe.subscriptions[o]
189 print "not lisenting to object at: ", o
191 if not noMain == True:
193 main_loop = gobject.MainLoop(None, False)
195 except KeyboardInterrupt:
198 traceback.print_stack()
199 elif command == "set":
200 if len(commandArgs) == 0:
201 commandArgs = ['help']
202 if len(commandArgs) and commandArgs[0] == "help":
203 print "ObjectName PropertyName VALUE [ZONE]"
205 if len(commandArgs) < 3:
206 print "set requires more arguments (see set help)"
208 objectName = commandArgs[0]
209 propertyName = commandArgs[1]
210 value = commandArgs[2]
212 if len(commandArgs) == 4:
213 zone = int(commandArgs[3])
214 managerInterface = getManager(bus)
215 object = managerInterface.FindObjectForZone(objectName, zone)
216 propertiesInterface = dbus.Interface(bus.get_object("org.automotive.message.broker", object),"org.freedesktop.DBus.Properties")
217 property = propertiesInterface.Get("org.automotive."+objectName, propertyName)
218 if property.__class__ == dbus.Boolean:
219 value = value.lower() == "true"
220 realValue = property.__class__(value)
221 propertiesInterface.Set("org.automotive."+objectName, propertyName, realValue)
222 property = propertiesInterface.Get("org.automotive."+objectName, propertyName)
223 if property == realValue:
224 print propertyName + " = ", property
226 print "Error setting property. Expected value: ", realValue, " Received: ", property
228 elif command == "getHistory":
229 if len(commandArgs) == 0:
230 commandArgs = ['help']
231 if commandArgs[0] == "help":
232 print "ObjectName [ZONE] [STARTTIME] [ENDTIME] "
234 if len(commandArgs) < 1:
235 print "getHistory requires more arguments (see getHistory help)"
237 objectName = commandArgs[0]
239 if len(commandArgs) >= 3:
240 start = float(commandArgs[2])
242 if len(commandArgs) >= 4:
243 end = float(commandArgs[3])
245 if len(commandArgs) >= 2:
246 zone = int(commandArgs[1])
247 managerInterface = getManager(bus)
248 object = managerInterface.FindObjectForZone(objectName, zone);
249 propertiesInterface = dbus.Interface(bus.get_object("org.automotive.message.broker", object),"org.automotive."+objectName)
250 print json.dumps(propertiesInterface.GetHistory(start, end), indent=2)
251 elif command == "plugin":
252 if len(commandArgs) == 0:
253 commandArgs = ['help']
254 if commandArgs[0] == 'help':
255 print "[list] [pluginName] [on/off]"
257 elif commandArgs[0] == 'list':
258 for plugin in listPlugins():
261 elif len(commandArgs) == 1:
262 for plugin in listPlugins():
263 if plugin['name'] == commandArgs[0]:
264 print json.dumps(plugin, indent=4)
267 print "name: " + plugin['name'] + "==?" + commandArgs[0]
268 print "plugin not found: ", commandArgs[0]
271 if len(commandArgs) < 2:
273 enArg = commandArgs[1]
274 if not enArg == "on" and not enArg == "off":
275 print "please use 'on' or 'off' to enable/disable the plugin"
277 plugin = commandArgs[0]
278 enabled = enArg == "on"
280 if enablePlugin(plugin, enabled):
284 print "Error could not enable", plugin
291 print "Invalid command"
296 parser = argparse.ArgumentParser(prog="ambctl", description='Automotive Message Broker DBus client tool', add_help=False)
297 parser.add_argument('command', metavar='COMMAND [help]', nargs='?', default='stdin', help='amb dbus command')
298 parser.add_argument('commandArgs', metavar='ARG', nargs='*',
299 help='amb dbus command arguments')
300 parser.add_argument('-h', '--help', help='print help', action='store_true')
302 args = parser.parse_args()
310 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
312 if args.command == "stdin":
317 promptAmbctl = "[ambctl]"
319 fullprompt = promptAmbctl + promptEnd
322 autocomplete = Autocomplete()
323 def full_line_len(self):
324 return len(self.fullprompt) + len(self.line)
325 def insert(self, str):
326 if self.curpos == len(self.line):
328 self.curpos = len(self.line)
330 self.line = self.line[:self.curpos] + str + self.line[self.curpos:]
332 def arrow_back(self):
338 def arrow_forward(self):
339 if self.curpos < len(self.line):
344 def back_space(self):
347 self.line = self.line[:self.curpos] + self.line[self.curpos+1:]
351 if self.curpos < len(self.line):
352 self.line = self.line[:self.curpos] + self.line[self.curpos+2:]
357 if len(self.history)-1 == 0 or len(self.history)-1 != self.historypos:
359 self.templine = self.line
362 self.history.append(self.line)
363 self.historypos = len(self.history)-1
368 self.curpos = len(self.line)
370 def history_up(self):
371 if self.historypos >= 0:
372 self.line = self.history[self.historypos]
373 if self.historypos != 0:
378 def history_down(self):
379 if self.historypos >= 0 and self.historypos < len(self.history)-1:
381 self.line = self.history[self.historypos]
384 self.historypos = len(self.history)-1
385 self.set(self.templine)
394 sys.stdout.write('\x1b[2K\x1b[80D')
397 sys.stdout.write('\x1b[1D')
400 sys.stdout.write('\x1b[1C')
402 def display_prompt():
403 sys.stdout.write(bcolors.OKBLUE+Data.promptAmbctl+bcolors.WHITE+Data.promptEnd);
408 sys.stdout.write(data.line)
409 cursorpos = len(data.line) - data.curpos
410 for x in xrange(cursorpos):
414 def handle_keyboard(source, cond, data):
416 #print "char: ", ord(str)
419 if ord(str[0]) == 27 and ord(str[1]) == 91 and ord(str[2]) == 68:
421 if data.arrow_back():
424 elif ord(str[0]) == 27 and ord(str[1]) == 91 and ord(str[2]) == 67:
426 if data.arrow_forward():
429 elif ord(str[0]) == 27 and ord(str[1]) == 91 and ord(str[2]) == 70:
431 while data.arrow_forward():
434 elif ord(str[0]) == 27 and ord(str[1]) == 91 and ord(str[2]) == 72: #home
435 while data.arrow_back():
438 elif len(str) == 4 and ord(str[0]) == 27 and ord(str[1]) == 91 and ord(str[2]) == 51 and ord(str[3]) == 126:
442 elif ord(str[0]) == 27 and ord(str[1]) == 91 and ord(str[2]) == 65:
446 while data.arrow_forward():
449 elif ord(str[0]) == 27 and ord(str[1]) == 91 and ord(str[2]) == 66:
452 while data.arrow_forward():
460 words = data.line.split(' ')
461 if words[0] == "quit":
462 termios.tcsetattr(fd, termios.TCSAFLUSH, old)
463 fcntl.fcntl(fd, fcntl.F_SETFL, oldflags)
467 processCommand(words[0], words[1:])
469 processCommand(words[0], [])
470 except dbus.exceptions.DBusException, error:
473 print "Error running command ", sys.exc_info()[0]
474 traceback.print_stack()
478 elif ord(str) == 127: #backspace
484 wordsList = data.line.split(' ')
485 toComplete = wordsList[-1]
486 results, samestring = data.autocomplete.complete(toComplete)
487 if len(samestring) and len(samestring) > len(toComplete) and not (samestring == toComplete):
488 if len(wordsList) > 1:
489 data.line = ' '.join(wordsList[0:-1]) + ' ' + samestring
491 data.line = samestring
492 while data.arrow_forward():
495 elif len(results) and not results[0] == toComplete:
497 print len(results), "results:"
498 if len(results) <= 3:
499 print ' '.join(results)
503 if len(r) > longestLen:
506 while i < len(results) / 3:
509 if len(results) < i+3:
510 numCols = len(results) - i
511 for n in xrange(numCols):
513 for n in xrange((longestLen + 5) - len(results[i])):
520 elif curses.ascii.isprint(ord(str)) or ord(str) == curses.ascii.SP: #regular text
525 print "@PROJECT_PRETTY_NAME@ @PROJECT_VERSION@"
528 fd = sys.stdin.fileno()
529 old = termios.tcgetattr(fd)
530 new = termios.tcgetattr(fd)
531 new[3] = new[3] & ~termios.ICANON & ~termios.ECHO
532 termios.tcsetattr(fd, termios.TCSANOW, new)
534 oldflags = fcntl.fcntl(fd, fcntl.F_GETFL)
535 fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK)
537 io_stdin = glib.IOChannel(fd)
538 io_stdin.add_watch(glib.IO_IN, handle_keyboard, data)
544 main_loop = gobject.MainLoop(None, False)
546 except KeyboardInterrupt:
549 traceback.print_stack()
551 termios.tcsetattr(fd, termios.TCSAFLUSH, old)
552 fcntl.fcntl(fd, fcntl.F_SETFL, oldflags)
558 processCommand(args.command, args.commandArgs, False)
559 except dbus.exceptions.DBusException, error: