8 import termios, fcntl, os
11 from gi.repository import GObject, GLib
13 from dbus.mainloop.glib import DBusGMainLoop
30 def __init__(self, n, d):
39 self.commands.append(Autocomplete.Cmd('help', 'Prints help data (also see COMMAND help)'))
40 self.commands.append(Autocomplete.Cmd('list', 'List supported ObjectNames'))
41 self.commands.append(Autocomplete.Cmd('get', 'Get properties from an ObjectName'))
42 self.commands.append(Autocomplete.Cmd('listen', 'Listen for changes on an ObjectName'))
43 self.commands.append(Autocomplete.Cmd('set', 'Set a property for an ObjectName'))
44 self.commands.append(Autocomplete.Cmd('getHistory', 'Get logged data within a time range'))
45 self.commands.append(Autocomplete.Cmd('plugin', 'enable, disable and get info on a plugin'))
46 self.commands.append(Autocomplete.Cmd('quit', 'Exit ambctl'))
49 bus = dbus.SystemBus()
50 managerObject = bus.get_object("org.automotive.message.broker", "/");
51 managerInterface = dbus.Interface(managerObject, "org.automotive.Manager")
52 self.properties = managerInterface.List()
53 except dbus.exceptions.DBusException, error:
56 def complete(self, partialString, commandsOnly = False):
61 for cmd in self.commands:
62 if not (len(partialString)) or cmd.name.startswith(partialString):
63 results.append(cmd.name)
66 for property in self.properties:
67 if not(len(partialString)) or property.startswith(partialString):
68 results.append(str(property))
70 if len(results) > 1 and len(results[0]) > 0:
71 for i in range(len(results[0])):
72 for j in range(len(results[0])-i+1):
73 if j > len(sameString) and all(results[0][i:i+j] in x for x in results):
74 sameString = results[0][i:i+j]
75 elif len(results) == 1:
76 sameString = results[0]
78 return results, sameString
82 help = ("Available commands:\n")
83 autocomplete = Autocomplete()
84 for cmd in autocomplete.commands:
85 help += bcolors.HEADER + cmd.name + bcolors.WHITE
86 for i in range(1, 15 - len(cmd.name)):
88 help += cmd.description + "\n"
92 def changed(interface, properties, invalidated):
93 print json.dumps(properties, indent=2)
97 for root, dirs, files in os.walk('@PLUGIN_SEGMENT_INSTALL_PATH@'):
99 fullpath = root + "/" + file;
100 pluginFile = open(fullpath)
102 data = json.load(pluginFile)
104 data['segmentPath'] = fullpath
106 except ValueError, e:
107 print "error parsing json file", file, ":", e
108 traceback.print_stack()
109 finally: pluginFile.close()
112 def enablePlugin(pluginName, enabled):
113 return setPluginProperty(pluginName, "enabled", enabled);
115 def setPluginProperty(pluginName, key, value):
119 if plugin["name"] == pluginName:
121 if key not in plugin:
122 print "Key not found: ", key
124 type = plugin[key].__class__
126 value = value.lower() == "true"
129 file = open(plugin["segmentPath"], 'rw+')
130 plugin.pop('segmentPath', None)
131 fixedData = json.dumps(plugin, separators=(', ', ' : '), indent=4)
132 fixedData = fixedData.replace(' ','\t');
134 file.write(fixedData)
137 except IOError, error:
143 def processCommand(command, commandArgs, noMain=True):
145 if command == 'help':
152 bus = dbus.SystemBus()
153 managerObject = bus.get_object("org.automotive.message.broker", "/");
154 managerInterface = dbus.Interface(managerObject, "org.automotive.Manager")
155 return managerInterface, bus
157 print "Error connecting to AMB. is AMB running?"
160 if command == "list" :
161 managerInterface, bus = getManager()
162 if managerInterface == None:
164 supportedList = managerInterface.List()
165 for objectName in supportedList:
168 elif command == "get":
169 if len(commandArgs) == 0:
170 commandArgs = ['help']
171 if commandArgs[0] == "help":
172 print "ObjectName [ObjectName...]"
174 managerInterface, bus = getManager()
175 if managerInterface == None:
177 for objectName in commandArgs:
178 objects = managerInterface.FindObject(objectName)
181 propertiesInterface = dbus.Interface(bus.get_object("org.automotive.message.broker", o),"org.freedesktop.DBus.Properties")
182 print json.dumps(propertiesInterface.GetAll("org.automotive."+objectName), indent=2)
184 elif command == "listen":
186 if len(commandArgs) == 0:
187 commandArgs = ['help']
188 if commandArgs[0] == "help":
189 print "[help] [off] ObjectName [ObjectName...]"
191 elif commandArgs[0] == "off":
193 commandArgs=commandArgs[1:]
194 managerInterface, bus = getManager()
195 if managerInterface == None:
197 for objectName in commandArgs:
198 objects = managerInterface.FindObject(objectName)
201 signalMatch = bus.add_signal_receiver(changed, dbus_interface="org.freedesktop.DBus.Properties", signal_name="PropertiesChanged", path=o)
202 Subscribe.subscriptions[o] = signalMatch
205 signalMatch = Subscribe.subscriptions.get(o)
207 del Subscribe.subscriptions[o]
209 print "not lisenting to object at: ", o
211 if not noMain == True:
213 main_loop = GObject.MainLoop()
215 except KeyboardInterrupt:
218 traceback.print_stack()
219 elif command == "set":
220 if len(commandArgs) == 0:
221 commandArgs = ['help']
222 if len(commandArgs) and commandArgs[0] == "help":
223 print "ObjectName PropertyName VALUE [ZONE]"
225 if len(commandArgs) < 3:
226 print "set requires more arguments (see set help)"
228 objectName = commandArgs[0]
229 propertyName = commandArgs[1]
230 value = commandArgs[2]
232 if len(commandArgs) == 4:
233 zone = int(commandArgs[3])
234 managerInterface, bus = getManager()
235 if managerInterface == None:
237 object = managerInterface.FindObjectForZone(objectName, zone)
238 propertiesInterface = dbus.Interface(bus.get_object("org.automotive.message.broker", object),"org.freedesktop.DBus.Properties")
239 property = propertiesInterface.Get("org.automotive."+objectName, propertyName)
240 if property.__class__ == dbus.Boolean:
241 value = value.lower() == "true"
242 realValue = property.__class__(value)
243 propertiesInterface.Set("org.automotive."+objectName, propertyName, realValue)
244 property = propertiesInterface.Get("org.automotive."+objectName, propertyName)
245 if property == realValue:
246 print propertyName + " = ", property
248 print "Error setting property. Expected value: ", realValue, " Received: ", property
250 elif command == "getHistory":
251 if len(commandArgs) == 0:
252 commandArgs = ['help']
253 if commandArgs[0] == "help":
254 print "ObjectName [ZONE] [STARTTIME] [ENDTIME] "
256 if len(commandArgs) < 1:
257 print "getHistory requires more arguments (see getHistory help)"
259 objectName = commandArgs[0]
261 if len(commandArgs) >= 3:
262 start = float(commandArgs[2])
264 if len(commandArgs) >= 4:
265 end = float(commandArgs[3])
267 if len(commandArgs) >= 2:
268 zone = int(commandArgs[1])
269 managerInterface, bus = getManager()
270 if managerInterface == None:
272 object = managerInterface.FindObjectForZone(objectName, zone);
273 propertiesInterface = dbus.Interface(bus.get_object("org.automotive.message.broker", object),"org.automotive."+objectName)
274 print json.dumps(propertiesInterface.GetHistory(start, end), indent=2)
275 elif command == "plugin":
276 if len(commandArgs) == 0:
277 commandArgs = ['help']
278 if commandArgs[0] == 'help':
279 print "[list] [pluginName] [key value]"
281 elif commandArgs[0] == 'list':
282 for plugin in listPlugins():
285 elif len(commandArgs) == 1:
286 for plugin in listPlugins():
287 if plugin['name'] == commandArgs[0]:
288 print json.dumps(plugin, indent=4)
291 print "name: " + plugin['name'] + "==?" + commandArgs[0]
292 print "plugin not found: ", commandArgs[0]
295 if len(commandArgs) < 3:
297 plugin = commandArgs[0]
299 value = commandArgs[2]
301 if not setPluginProperty(plugin, key, value):
302 print "Could not set property"
303 print plugin, key, ":", value
307 print "Invalid command"
312 parser = argparse.ArgumentParser(prog="ambctl", description='Automotive Message Broker DBus client tool', add_help=False)
313 parser.add_argument('command', metavar='COMMAND [help]', nargs='?', default='stdin', help='amb dbus command')
314 parser.add_argument('commandArgs', metavar='ARG', nargs='*',
315 help='amb dbus command arguments')
316 parser.add_argument('-h', '--help', help='print help', action='store_true')
318 args = parser.parse_args()
326 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
328 if args.command == "stdin":
333 promptAmbctl = "[ambctl]"
335 fullprompt = promptAmbctl + promptEnd
338 autocomplete = Autocomplete()
339 def full_line_len(self):
340 return len(self.fullprompt) + len(self.line)
341 def insert(self, str):
342 if self.curpos == len(self.line):
344 self.curpos = len(self.line)
346 self.line = self.line[:self.curpos] + str + self.line[self.curpos:]
348 def arrow_back(self):
354 def arrow_forward(self):
355 if self.curpos < len(self.line):
360 def back_space(self):
363 self.line = self.line[:self.curpos] + self.line[self.curpos+1:]
367 if self.curpos < len(self.line):
368 self.line = self.line[:self.curpos] + self.line[self.curpos+2:]
373 if len(self.history)-1 == 0 or len(self.history)-1 != self.historypos:
375 self.templine = self.line
378 self.history.append(self.line)
379 self.historypos = len(self.history)-1
384 self.curpos = len(self.line)
386 def history_up(self):
387 if self.historypos >= 0:
388 self.line = self.history[self.historypos]
389 if self.historypos != 0:
394 def history_down(self):
395 if self.historypos >= 0 and self.historypos < len(self.history)-1:
397 self.line = self.history[self.historypos]
400 self.historypos = len(self.history)-1
401 self.set(self.templine)
410 sys.stdout.write('\x1b[2K\x1b[80D')
413 sys.stdout.write('\x1b[1D')
416 sys.stdout.write('\x1b[1C')
418 def display_prompt():
419 sys.stdout.write(bcolors.OKBLUE+Data.promptAmbctl+bcolors.WHITE+Data.promptEnd);
424 sys.stdout.write(data.line)
425 cursorpos = len(data.line) - data.curpos
426 for x in xrange(cursorpos):
430 def handle_keyboard(source, cond, data):
432 #print "char: ", ord(str)
435 if ord(str[0]) == 27 and ord(str[1]) == 91 and ord(str[2]) == 68:
437 if data.arrow_back():
440 elif ord(str[0]) == 27 and ord(str[1]) == 91 and ord(str[2]) == 67:
442 if data.arrow_forward():
445 elif ord(str[0]) == 27 and ord(str[1]) == 91 and ord(str[2]) == 70:
447 while data.arrow_forward():
450 elif ord(str[0]) == 27 and ord(str[1]) == 91 and ord(str[2]) == 72: #home
451 while data.arrow_back():
454 elif len(str) == 4 and ord(str[0]) == 27 and ord(str[1]) == 91 and ord(str[2]) == 51 and ord(str[3]) == 126:
458 elif ord(str[0]) == 27 and ord(str[1]) == 91 and ord(str[2]) == 65:
462 while data.arrow_forward():
465 elif ord(str[0]) == 27 and ord(str[1]) == 91 and ord(str[2]) == 66:
468 while data.arrow_forward():
476 words = data.line.split(' ')
477 if words[0] == "quit":
478 termios.tcsetattr(fd, termios.TCSAFLUSH, old)
479 fcntl.fcntl(fd, fcntl.F_SETFL, oldflags)
483 processCommand(words[0], words[1:])
485 processCommand(words[0], [])
486 except dbus.exceptions.DBusException, error:
491 elif ord(str) == 127: #backspace
497 wordsList = data.line.split(' ')
498 toComplete = wordsList[-1]
499 results, samestring = data.autocomplete.complete(toComplete)
500 if len(samestring) and len(samestring) > len(toComplete) and not (samestring == toComplete):
501 if len(wordsList) > 1:
502 data.line = ' '.join(wordsList[0:-1]) + ' ' + samestring
504 data.line = samestring
505 while data.arrow_forward():
508 elif len(results) and not results[0] == toComplete:
510 if len(results) <= 3:
511 print ' '.join(results)
515 if len(r) > longestLen:
518 while i < len(results):
521 if len(results) < i+3:
522 numCols = len(results) - i
523 for n in xrange(numCols):
525 for n in xrange((longestLen + 5) - len(results[i])):
531 elif curses.ascii.isprint(ord(str)) or ord(str) == curses.ascii.SP: #regular text
536 print "@PROJECT_PRETTY_NAME@ @PROJECT_VERSION@"
539 fd = sys.stdin.fileno()
540 old = termios.tcgetattr(fd)
541 new = termios.tcgetattr(fd)
542 new[3] = new[3] & ~termios.ICANON & ~termios.ECHO
543 termios.tcsetattr(fd, termios.TCSANOW, new)
545 oldflags = fcntl.fcntl(fd, fcntl.F_GETFL)
546 fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK)
548 io_stdin = GLib.IOChannel(fd)
549 io_stdin.add_watch(GLib.IO_IN, handle_keyboard, data)
555 main_loop = GObject.MainLoop()
557 except KeyboardInterrupt:
560 termios.tcsetattr(fd, termios.TCSAFLUSH, old)
561 fcntl.fcntl(fd, fcntl.F_SETFL, oldflags)
567 processCommand(args.command, args.commandArgs, False)
568 except dbus.exceptions.DBusException, error: