Ejemplo n.º 1
0
class Employee(HasTraits):

    # Define the traits:
    name = Str
    dept = Str
    email = Str

    # Define the view:
    view = View(VGroup(
        VGroup(
            Item('name',
                 show_label=False,
                 editor=ImageEditor(
                     image=ImageResource('info', search_path=search_path)))),
        VGroup(
            Item('name'),
            Item('dept'),
            Item('email'),
            Item('picture',
                 editor=ImageEditor(scale=True,
                                    preserve_aspect_ratio=True,
                                    allow_upscaling=True),
                 springy=True),
        )),
                resizable=True)
Ejemplo n.º 2
0
    def test_image_editor_resource(self):
        obj1 = ImageDisplay(image=ImageResource(filename1))
        view = View(Item('image', editor=ImageEditor()))

        # This should not fail.
        with create_ui(obj1, dict(view=view)) as ui:
            obj1.image = ImageResource(filename2)
Ejemplo n.º 3
0
    def default_traits_view(self):

        table_editor = TableEditor(columns=[
            ObjectColumn(name="name", label="name", resize_mode="stretch"),
            ObjectColumn(name="tag", label="File Type", resize_mode="fixed")
        ],
                                   auto_size=False,
                                   selected='object.selected_files',
                                   selection_mode='rows',
                                   editable=False)

        file_editor = FileEditor(allow_dir=True, filter=['*.tif'])

        image_editor = ImageEditor(scale=True,
                                   allow_upscaling=False,
                                   preserve_aspect_ratio=True)

        traits_view = View(VGroup(
            Group(UItem('image', editor=image_editor)),
            Group(Item('file_search', editor=file_editor, style='custom'),
                  Item('add_file_button', label='Add File'),
                  show_labels=False),
            HGroup(
                Item('key', editor=TextEditor(), style='simple'),
                Item('filter_file_button', label='Filter'),
            ),
            Group(Item('file_table', editor=table_editor),
                  Item('remove_file_button', label='Remove File'),
                  show_labels=False)),
                           style='custom',
                           resizable=True)

        return traits_view
Ejemplo n.º 4
0
    def test_image_editor_none(self):

        obj1 = ImageDisplay(image=None)
        view = View(Item('image', editor=ImageEditor()))

        # This should not fail.
        with create_ui(obj1, dict(view=view)) as ui:
            pass
Ejemplo n.º 5
0
class ImageItem(HasPrivateTraits):

    # The name of the item being displayed:
    name = Str

    # The image being displayed:
    image = Image

    #-- Traits UI View Definitions ---------------------------------------------

    view = View(Item('image', show_label=False, editor=ImageEditor()))
Ejemplo n.º 6
0
class ImageInfo(MFileDialogModel):
    """ Defines a file dialog extension that display an image file's dimensions
        and content.
    """

    # The ImageResource object for the current file:
    image = Property(depends_on='file_name')

    # The width of the current image:
    width = Property(depends_on='image')

    # The height of the current image:
    height = Property(depends_on='image')

    #-- Traits View Definitions ------------------------------------------------

    view = View(
        VGroup(
            VGroup(Item('width', style='readonly'),
                   Item('height', style='readonly'),
                   label='Image Dimensions',
                   show_border=True),
            VGroup(Item('image', show_label=False, editor=ImageEditor()),
                   label='Image',
                   show_border=True,
                   springy=True)))

    #-- Property Implementations -----------------------------------------------

    @cached_property
    def _get_image(self):
        path, name = split(self.file_name)
        if splitext(name)[1] in ('.png', '.gif', '.jpg', '.jpeg'):
            image = ImageResource(name, search_path=[path])
        else:
            image = ImageResource('unknown')
        self._cur_image = image.create_image()
        return image

    @cached_property
    def _get_width(self):
        try:
            return str(toolkit().image_size(self._cur_image)[0]) + ' pixels'
        except:
            return '---'

    @cached_property
    def _get_height(self):
        try:
            return str(toolkit().image_size(self._cur_image)[1]) + ' pixels'
        except:
            return '---'
Ejemplo n.º 7
0
class ImageViewerPane(TraitsTaskPane):

    model = Instance(ImageViewer, ())

    view = View(
        Item('image',
             editor=ImageEditor(
                 scale=False,
                 preserve_aspect_ratio=True,
             ),
             show_label=False,
             visible_when='image_file != ""'),
        scrollable=True,
        resizable=True,
    )
Ejemplo n.º 8
0
    def default_traits_view(self):

        traits_view = View(
            Group(
                UItem(
                    'image',
                    editor=ImageEditor(
                        scale=True,
                        allow_upscaling=False,
                        preserve_aspect_ratio=True)
                    )
                )
        )

        return traits_view
Ejemplo n.º 9
0
class ImageViewer(HasTraits):

    path = File('saturn.jpg')

    image = Property(Instance(ImageResource), depends_on=['path'])

    @cached_property
    def _get_image(self):
        return ImageResource(self.path)

    view = View(
        Item('image',
             editor=ImageEditor(scale=False,
                                preserve_aspect_ratio=True,
                                allow_upscaling=True),
             springy=True,
             show_label=False,
             visible_when='image_file != ""'),
        scrollable=True,
        resizable=True,
    )
Ejemplo n.º 10
0
    def test_image_editor_pillow(self):
        try:
            import PIL.Image
            from pyface.api import PILImage
        except ImportError:
            self.skipTest("Pillow is not available")
        if is_qt:
            try:
                # is ImageQt available as well
                from PIL.ImageQt import ImageQt
            except ImportError:
                self.skipTest("ImageQt is not available")

        pil_image_1 = PIL.Image.open(filename1)
        pil_image_2 = PIL.Image.open(filename2)

        obj1 = ImageDisplay(image=PILImage(image=pil_image_1))
        view = View(Item('image', editor=ImageEditor()))

        # This should not fail.
        with create_ui(obj1, dict(view=view)) as ui:
            obj1.image = PILImage(image=pil_image_2)
Ejemplo n.º 11
0
    def test_image_editor_array(self):
        try:
            import numpy as np
            from pyface.api import ArrayImage
        except ImportError:
            self.skipTest("NumPy is not available")

        gradient1 = np.empty(shape=(256, 256, 3), dtype='uint8')
        gradient1[:, :, 0] = np.arange(256).reshape(256, 1)
        gradient1[:, :, 1] = np.arange(256).reshape(1, 256)
        gradient1[:, :, 2] = np.arange(255, -1, -1).reshape(1, 256)

        gradient2 = np.empty(shape=(256, 256, 3), dtype='uint8')
        gradient2[:, :, 0] = np.arange(255, -1, -1).reshape(256, 1)
        gradient2[:, :, 1] = np.arange(256).reshape(1, 256)
        gradient2[:, :, 2] = np.arange(255, -1, -1).reshape(1, 256)

        obj1 = ImageDisplay(image=ArrayImage(data=gradient1))
        view = View(Item('image', editor=ImageEditor()))

        # This should not fail.
        with create_ui(obj1, dict(view=view)) as ui:
            obj1.image = ArrayImage(data=gradient2)
Ejemplo n.º 12
0
class FileExistsHandler(Handler):
    """ Controller for the 'file already exists' popup.
    """
    # The current status message:
    message = Str

    # The OK and Cancel buttons:
    ok = Button('OK')
    cancel = Button('Cancel')

    #-- Traits View Definitions ------------------------------------------------

    view = View(VGroup(
        HGroup(Item('handler.message',
                    editor=ImageEditor(image='@icons:dialog-warning')),
               Item('handler.message', style='readonly'),
               show_labels=False),
        HGroup(spring,
               Item('handler.ok'),
               Item('handler.cancel'),
               show_labels=False)),
                kind='popup')

    #-- Handler Event Handlers -------------------------------------------------

    def handler_ok_changed(self, info):
        """ Handles the user clicking the OK button.
        """
        parent = info.ui.parent
        info.ui.dispose(True)
        parent.dispose(True)

    def handler_cancel_changed(self, info):
        """ Handles the user clicking the Cancel button.
        """
        info.ui.dispose(False)
Ejemplo n.º 13
0
class Employee ( HasTraits ):

    # Define the traits:
    name  = Str
    dept  = Str
    email = Str

    # Define the view:
    view = View(
        VGroup(
            VGroup(
                Item( 'name',
                      show_label = False,
                      editor = ImageEditor(
                          image = ImageResource( 'info',
                                                 search_path = search_path) ) )
            ),
            VGroup(
                Item( 'name' ),
                Item( 'dept' ),
                Item( 'email' )
            )
        )
    )
Ejemplo n.º 14
0
class SwiftConsole(HasTraits):
  """Traits-defined Swift Console.

  link : object
    Serial driver
  update : bool
    Update the firmware
  log_level_filter : str
    Syslog string, one of "ERROR", "WARNING", "INFO", "DEBUG".
  skip_settings : bool
    Don't read the device settings. Set to False when the console is reading
    from a network connection only.

  """

  link = Instance(sbpc.Handler)
  console_output = Instance(OutputList())
  python_console_env = Dict
  device_serial = Str('')
  dev_id = Str('')
  tracking_view = Instance(TrackingView)
  solution_view = Instance(SolutionView)
  baseline_view = Instance(BaselineView)
  observation_view = Instance(ObservationView)
  networking_view = Instance(SbpRelayView)
  observation_view_base = Instance(ObservationView)
  system_monitor_view = Instance(SystemMonitorView)
  settings_view = Instance(SettingsView)
  update_view = Instance(UpdateView)
  log_level_filter = Enum(list(SYSLOG_LEVELS.itervalues()))


  """"
  mode : baseline and solution view - SPP, Fixed or Float
  num_sat : baseline and solution view - number of satellites
  port : which port is Piksi connected to
  directory_name : location of logged files
  json_logging : enable JSON logging
  csv_logging : enable CSV logging 
  is_valid_directory : check to see if chosen directory is valid

  """

  mode = Str('') 
  num_signals = Int(0)
  port = Str('')
  latency = Int()
  directory_name = Directory
  json_logging = Bool(True)
  csv_logging = Bool(False)
  cnx_icon = Str('')
  heartbeat_count = Int()
  last_timer_heartbeat = Int()
  solid_connection = Bool(False)
  timer = Any()
  is_valid_directory = Bool (True)


  csv_logging_button = SVGButton(
   toggle=True, label='CSV log', tooltip='start CSV logging', toggle_tooltip='stop CSV logging', 
   filename=os.path.join(determine_path(), 'images', 'iconic', 'pause.svg'),
   toggle_filename=os.path.join(determine_path(), 'images', 'iconic', 'play.svg'),
   orientation = 'vertical',
   width=2, height=2,
  )
  json_logging_button = SVGButton(
   toggle=True, label='JSON log', tooltip='start JSON logging', toggle_tooltip='stop JSON logging', 
   filename=os.path.join(determine_path(), 'images', 'iconic', 'pause.svg'),
   toggle_filename=os.path.join(determine_path(), 'images', 'iconic', 'play.svg'),
   orientation = 'vertical',
   width=2, height=2,
  )
  paused_button = SVGButton(
    label='', tooltip='Pause console update', toggle_tooltip='Resume console update', toggle=True,
    filename=os.path.join(determine_path(), 'images', 'iconic', 'pause.svg'),
    toggle_filename=os.path.join(determine_path(), 'images', 'iconic', 'play.svg'),
    width=8, height=8
  )
  clear_button = SVGButton(
    label='', tooltip='Clear console buffer',
    filename=os.path.join(determine_path(), 'images', 'iconic', 'x.svg'),
    width=8, height=8
  )

  view = View(
    VSplit(
      Tabbed(
        Item('tracking_view', style='custom', label='Tracking'),
        Item('solution_view', style='custom', label='Solution'),
        Item('baseline_view', style='custom', label='Baseline'),
        VSplit(
          Item('observation_view', style='custom', show_label=False),
          Item('observation_view_base', style='custom', show_label=False),
          label='Observations',
        ),
        Item('settings_view', style='custom', label='Settings'),
        Item('update_view', style='custom', label='Firmware Update'),
        Tabbed(
          Item('system_monitor_view', style='custom', label='System Monitor'),
          Item('networking_view', label='Networking', style='custom', show_label=False),
          Item('python_console_env', style='custom',
            label='Python Console', editor=ShellEditor()),
          label='Advanced',
          show_labels=False
         ),
        show_labels=False
      ),
      VGroup(
        VGroup(
          HGroup(
            Spring(width=4, springy=False),
            Item('paused_button', show_label=False, padding=0, width=8, height=8),
            Item('clear_button', show_label=False, width=8, height=8),
            Item('', label='Console Log', emphasized=True),
            Item('csv_logging_button', emphasized=True, show_label=False, width=12, height=-30, padding=0),
            Item('json_logging_button', emphasized=True, show_label=False, width=12, height=-30, padding=0),
            Item('directory_name', show_label=False, springy=True, tooltip='Choose location for file logs. Default is home/SwiftNav.', 
              height=-25, enabled_when='not(json_logging or csv_logging)'),
            UItem('log_level_filter', style='simple', padding=0, height=8, show_label=True,
                tooltip='Show log levels up to and including the selected level of severity.\nThe CONSOLE log level is always visible.'),
        ),       
        Item(
          'console_output',
          style='custom',
          editor=InstanceEditor(),
          height=125,
          show_label=False,
          full_size=True
        ),
        ),
        HGroup(
          Spring(width=4, springy=False),
          Item('', label='PORT:', emphasized=True, tooltip='Serial Port that Piksi is connected to'),
          Item('port', show_label=False, style = 'readonly'),
          Item('', label='FIX TYPE:', emphasized = True, tooltip='Piksi Mode: SPS, Float RTK, Fixed RTK'),
          Item('mode', show_label = False, style = 'readonly'),
          Item('', label='#Signals:', emphasized=True, tooltip='Number of signals acquired by Piksi'),
          Item('num_signals', padding=2, show_label=False, style = 'readonly'),
          Item('', label='Base Latency:', emphasized=True, tooltip='Corrections latency (-1 means no corrections)'),
          Item('latency', padding=2, show_label=False, style = 'readonly'),     
          Spring(springy=True),
          Item('cnx_icon', show_label = False, padding=0, width=8, height=8, visible_when='solid_connection',
               springy=False, editor=ImageEditor(allow_clipping=False, image = ImageResource( 'arrows_blue.png', 
                                                search_path=[os.path.join(determine_path(), 'images', 'iconic')]))),
          Item('cnx_icon', show_label = False, padding=0, width=8, height=8, visible_when='not solid_connection',
               springy=False, editor=ImageEditor(allow_clipping=False, image = ImageResource( 'arrows_grey.png',
                                                search_path=[os.path.join(determine_path(), 'images', 'iconic')]))),
          Spring(width=4, height=-2, springy=False),
        ),
       Spring(height=1, springy=False),
      ),
    ),
    icon=icon,
    resizable=True,
    width=800,
    height=600,
    handler=ConsoleHandler(),
    title=CONSOLE_TITLE
  )

  
  def print_message_callback(self, sbp_msg, **metadata):
    try:
      encoded = sbp_msg.payload.encode('ascii', 'ignore')
      for eachline in reversed(encoded.split('\n')):
        self.console_output.write_level(eachline,
                                        str_to_log_level(eachline.split(':')[0]))
    except UnicodeDecodeError:
      print "Critical Error encoding the serial stream as ascii."

  def log_message_callback(self, sbp_msg, **metadata):
    try:
      encoded = sbp_msg.text.encode('ascii', 'ignore')
      for eachline in reversed(encoded.split('\n')):
        self.console_output.write_level(eachline, sbp_msg.level)
    except UnicodeDecodeError:
      print "Critical Error encoding the serial stream as ascii."

  def ext_event_callback(self, sbp_msg, **metadata):
    e = MsgExtEvent(sbp_msg)
    print 'External event: %s edge on pin %d at wn=%d, tow=%d, time qual=%s' % (
      "Rising" if (e.flags & (1<<0)) else "Falling", e.pin, e.wn, e.tow,
      "good" if (e.flags & (1<<1)) else "unknown")

  def _paused_button_fired(self):
    self.console_output.paused = not self.console_output.paused

  def _log_level_filter_changed(self):
    """
    Takes log level enum and translates into the mapped integer.
    Integer stores the current filter value inside OutputList.
    """
    self.console_output.log_level_filter = str_to_log_level(self.log_level_filter)

  def _clear_button_fired(self):
    self.console_output.clear()

  def _directory_name_changed(self):
    if os.path.isdir(self.directory_name):
      self.is_valid_directory = True
      if self.baseline_view and self.solution_view:
        self.baseline_view.directory_name_b = self.directory_name
        self.solution_view.directory_name_p = self.directory_name
        self.solution_view.directory_name_v = self.directory_name
      if self.observation_view and self.observation_view_base:
        self.observation_view.dirname = self.directory_name
        self.observation_view_base.dirname = self.directory_name
    else:
      print "Please enter a valid directory!"
      self.is_valid_directory = False
  
  def check_heartbeat(self):
    # if our heartbeat hasn't changed since the last timer interval the connection must have dropped
    if self.heartbeat_count == self.last_timer_heartbeat:
      self.solid_connection = False
    else:
      self.solid_connection = True
    self.last_timer_heartbeat = self.heartbeat_count
      
  def update_on_heartbeat(self, sbp_msg, **metadata):
    self.heartbeat_count += 1
     # First initialize the state to nothing, if we can't update, it will be none
    temp_mode = "None"
    temp_num_signals = 0
    view = None
    # If we have a recent baseline update, we use the baseline info
    if time.time() - self.baseline_view.last_btime_update < 10:
      view = self.baseline_view
    # Otherwise, if we have a recent SPP update, we use the SPP
    elif time.time() - self.solution_view.last_stime_update < 10:
      view = self.solution_view
    if view:
      if view.last_soln:
        # if all is well we update state
        temp_mode = view.mode_string(view.last_soln)
        temp_num_signals = view.last_soln.n_sats
    
    self.mode = temp_mode
    self.num_signals = temp_num_signals

    if self.settings_view: # for auto populating surveyed fields 
      self.settings_view.lat = self.solution_view.latitude
      self.settings_view.lon = self.solution_view.longitude
      self.settings_view.alt = self.solution_view.altitude
    if self.system_monitor_view:
      self.latency = self.system_monitor_view.msg_obs_window_latency_ms

  def _csv_logging_button_fired(self):
    if self.is_valid_directory:
      if self.csv_logging and self.baseline_view.logging_b and self.solution_view.logging_p and self.solution_view.logging_v:
        print "Stopped CSV logging"
        self.csv_logging =  False
        self.baseline_view.logging_b = False
        self.solution_view.logging_p = False
        self.solution_view.logging_v = False

      else: 
        print "Started CSV logging at %s" % self.directory_name
        self.csv_logging = True
        self.baseline_view.logging_b = True
        self.solution_view.logging_p = True
        self.solution_view.logging_v = True
    else:
      print "Directory not valid"
      
  def _start_json_logging(self, override_filename=None):
    if override_filename:
      filename = override_filename
    else:
      filename = s.logfilename()
    filename = os.path.normpath(os.path.join(self.directory_name, filename))
    self.logger = s.get_logger(True, filename)
    self.forwarder = sbpc.Forwarder(self.link, self.logger)
    self.forwarder.start()

  def _stop_json_logging(self):
    fwd = self.forwarder
    fwd.stop()
    self.logger.flush()
    self.logger.close()

  def _json_logging_button_fired(self):
    if self.is_valid_directory:
      if self.first_json_press and self.json_logging:
        print "JSON Logging initiated via CMD line.  Please press button again to stop logging"
      elif self.json_logging:
        self._stop_json_logging()
        self.json_logging = False
        print "Stopped JSON logging"
      else:
        self._start_json_logging()
        self.json_logging = True
      self.first_json_press = False
    else: 
      print "Directory not valid"

  def __enter__(self):
    return self
  
  def __exit__(self, exc_type, exc_value, traceback):
    self.console_output.close() 
  
  def __init__(self, link, update, log_level_filter, skip_settings=False, error=False, 
               port=None, json_logging=False, log_dirname=None):
    self.error = error
    self.port = port
    self.dev_id = str(os.path.split(port)[1])
    self.num_signals = 0
    self.mode = ''
    self.forwarder = None
    self.latency = -1
    # if we have passed a logfile, we set our directory to it
    override_filename = None
    swift_path = None
    home = expanduser("~")
    swift_path = os.path.normpath(os.path.join(home, 'SwiftNav'))
    try: 
      os.makedirs(swift_path)
    except OSError:
      if not os.path.isdir(swift_path):
        raise

    if log_dirname:
        self.directory_name = log_dirname
    else:
      self.directory_name = swift_path
    
    # Start swallowing sys.stdout and sys.stderr
    self.console_output = OutputList(tfile=True, outdir=self.directory_name)
    sys.stdout = self.console_output
    self.console_output.write("Console: starting...")
    if not error:
      sys.stderr = self.console_output

    self.log_level_filter = log_level_filter
    self.console_output.log_level_filter = str_to_log_level(log_level_filter)
    try:
      self.link = link
      self.link.add_callback(self.print_message_callback, SBP_MSG_PRINT_DEP)
      self.link.add_callback(self.log_message_callback, SBP_MSG_LOG)
      self.link.add_callback(self.ext_event_callback, SBP_MSG_EXT_EVENT)
      self.link.add_callback(self.update_on_heartbeat, SBP_MSG_HEARTBEAT)
      self.dep_handler = DeprecatedMessageHandler(link)
      settings_read_finished_functions = []
      self.tracking_view = TrackingView(self.link)
      self.solution_view = SolutionView(self.link, dirname=self.directory_name)
      self.baseline_view = BaselineView(self.link, dirname=self.directory_name)
      self.observation_view = ObservationView(self.link, name='Local', relay=False, dirname=self.directory_name)
      self.observation_view_base = ObservationView(self.link, name='Remote', relay=True, dirname=self.directory_name)
      self.system_monitor_view = SystemMonitorView(self.link)
      self.update_view = UpdateView(self.link, prompt=update)
      settings_read_finished_functions.append(self.update_view.compare_versions)
      self.networking_view = SbpRelayView(self.link)
      self.json_logging = json_logging
      self.csv_logging = False
      self.first_json_press = True
      if json_logging:
        self._start_json_logging(override_filename)
        self.json_logging = True
      # we set timer interval to 1200 milliseconds because we expect a heartbeat each second
      self.timer = Timer(1200, self.check_heartbeat) 
      # Once we have received the settings, update device_serial with
      # the Piksi serial number which will be displayed in the window
      # title. This callback will also update the header route as used
      # by the networking view.
      def update_serial():
        serial_string = self.settings_view.settings['system_info']['serial_number'].value
        self.device_serial = 'PK%04d' % int(serial_string)
        if serial_string:
          self.networking_view.set_route(int(serial_string))
      settings_read_finished_functions.append(update_serial)
      self.settings_view = SettingsView(self.link,
                                        settings_read_finished_functions,
                                        skip=skip_settings)
      self.update_view.settings = self.settings_view.settings
      self.python_console_env = { 'send_message': self.link,
                                  'link': self.link, }
      self.python_console_env.update(self.tracking_view.python_console_cmds)
      self.python_console_env.update(self.solution_view.python_console_cmds)
      self.python_console_env.update(self.baseline_view.python_console_cmds)
      self.python_console_env.update(self.observation_view.python_console_cmds)
      self.python_console_env.update(self.networking_view.python_console_cmds)
      self.python_console_env.update(self.system_monitor_view.python_console_cmds)
      self.python_console_env.update(self.update_view.python_console_cmds)
      self.python_console_env.update(self.settings_view.python_console_cmds)

    except:
      import traceback
      traceback.print_exc()
      if self.error:
        sys.exit(1)
Ejemplo n.º 15
0
class OptionsPane(TraitsDockPane):

    id = 'pyfibre.options_pane'

    name = 'Options Pane'

    #: Remove the possibility to close the pane
    closable = False

    #: Remove the possibility to detach the pane from the GUI
    floatable = False

    #: Remove the possibility to move the pane in the GUI
    movable = False

    #: Make the pane visible by default
    visible = True

    # Overwrite options
    ow_metric = Bool(False)

    ow_segment = Bool(False)

    ow_network = Bool(False)

    save_figures = Bool(False)

    # Image analysis parameters
    sigma = Float(0.5)

    low_intensity = Int(1)

    high_intensity = Int(99)

    n_denoise = Int(5)

    m_denoise = Int(35)

    alpha = Float(0.5)

    image_editor = ImageEditor(scale=True,
                               allow_upscaling=False,
                               preserve_aspect_ratio=True)

    int_range_editor = RangeEditor(low=1, high=100, mode='slider')

    pix_range_editor = RangeEditor(low=2, high=50, mode='slider')

    traits_view = View(
        VGroup(
            Item('ow_network', label="Overwrite Network?"),
            Item('ow_segment', label="Overwrite Segments?"),
            Item('ow_metric', label="Overwrite Metrics?"),
            Item('save_figures', label="Save Figures?"),
            Item('sigma', label="Gaussian Std Dev (pix)"),
            Item('alpha', label="Alpha network coefficient"),
            Group(
                Item('low_intensity',
                     editor=int_range_editor,
                     style='custom',
                     label="Low Clip Intensity (%)"),
                Item('high_intensity',
                     editor=int_range_editor,
                     style='custom',
                     label="High Clip Intensity (%)")),
            Group(
                Item('n_denoise',
                     editor=pix_range_editor,
                     style='custom',
                     label="NL-Mean Neighbourhood 1 (pix)"),
                Item('m_denoise',
                     editor=pix_range_editor,
                     style='custom',
                     label="NL-Mean Neighbourhood 2 (pix)"))))
Ejemplo n.º 16
0
class NewAccountView(ModelView):
    """ Account creation dialog example.
    """

    #: Text explaining the dialog.
    explanation = Property(HTML,
                           depends_on=['_password_suggestions', '+view_error'])

    #: The user's password entered a second time.
    password = Password

    #: The user's password strength.
    password_strength = Range(0, 4)

    #: Alert icon for username error.
    password_strength_icon = Property(Image, depends_on='password_strength')

    #: Alert icon for username error.
    username_icon = Image('@std:alert16')

    #: Alert icon for second password error.
    password_match_icon = Image('@std:alert16')

    # private traits ---------------------------------------------------------

    #: The suggestions for a stronger password.
    _password_suggestions = Unicode

    #: Whether there is anything entered for the username.
    _username_error = Bool(False, view_error=True)

    #: Whether the password is strong enough.
    _password_strength_error = Bool(False, view_error=True)

    #: Whether the two entered passwords match.
    _password_match_error = Bool(False, view_error=True)

    # ------------------------------------------------------------------------
    # Handler interface
    # ------------------------------------------------------------------------

    def init(self, info):
        """ Initialize the error state of the object. """
        obj = info.object
        model = info.model

        # check for initial error states
        obj._check_username(model.username)
        obj._check_password_strength(model.password)
        obj._check_password_match(model.password)

        super(NewAccountView, self).init(info)

    def close(self, info, is_ok):
        """ Handles the user attempting to close the dialog.

        If it is via the OK dialog button, try to create an account before
        closing. If this fails, display an error message and veto the close
        by returning false.
        """
        if is_ok:
            success, message = info.model.create_account()
            if not success:
                dlg = MessageDialog(message="Cannot create account",
                                    informative=message,
                                    severity='error')
                dlg.open()
                return False

        return True

    # UI change handlers -----------------------------------------------------

    def model_username_changed(self, ui_info):
        """ Set error condition if the model's username is empty. """
        if ui_info.initialized:
            ui_info.object._username_error = (ui_info.model.username == '')

    def model_password_changed(self, ui_info):
        """ Check the quality of the password that the user entered. """
        if ui_info.initialized:
            obj = ui_info.object
            password = ui_info.model.password

            obj._check_password_strength(password)
            obj._check_password_match(password)

    def object_password_changed(self, ui_info):
        """ Check if the re-enteredpassword matches the original. """
        if ui_info.initialized:
            obj = ui_info.object
            password = ui_info.model.password

            obj._check_password_match(password)

    # ------------------------------------------------------------------------
    # private interface
    # ------------------------------------------------------------------------

    def _check_username(self, username):
        """ Check whether the passwords match. """
        self._username_error = (username == '')

    def _check_password_strength(self, password):
        """ Check the strength of the password

        This sets the password strength, suggestions for making a better
        password and an error state if the password is not strong enough.
        """
        if password:
            password_check = test_strength(password)
            self.password_strength = password_check['score']
            feedback = password_check.get('feedback', {})
            if feedback.get('warnings'):
                warnings = '<em>{}</em> '.format(feedback['warnings'])
            else:
                warnings = ''
            suggestions = feedback.get('suggestions', [])
            self._password_suggestions = warnings + ' '.join(suggestions)
        else:
            self.password_strength = 0
            self._password_suggestions = 'The password cannot be empty.'

        self._password_strength_error = (self.password_strength < 3)

    def _check_password_match(self, password):
        """ Check whether the passwords match. """
        self._password_match_error = (not password
                                      or password != self.password)

    # Trait change handlers --------------------------------------------------

    @on_trait_change("+view_error")
    def _view_error_updated(self, new_error):
        """ One of the error traits changed: update the error count. """
        if self.info and self.info.ui:
            if new_error:
                self.info.ui.errors += 1
            else:
                self.info.ui.errors -= 1

    # Traits property handlers -----------------------------------------------

    @cached_property
    def _get_password_strength_icon(self):
        """ Get the icon for password strength. """
        return strength_map[self.password_strength]

    @cached_property
    def _get_explanation(self):
        """ Get the explanatory HTML. """
        text = ''
        if self._username_error:
            text += 'The username cannot be empty. '
        if self._password_match_error:
            text += 'The passwords must match. '
        if self._password_suggestions:
            text += self._password_suggestions
        if not text:
            text = ("The username is valid, the password is strong and both " +
                    "password fields match.")
        return explanation_template.format(css=css, text=text)

    # TraitsUI view ----------------------------------------------------------

    view = View(
        VGroup(
            Item('explanation', show_label=False),
            VGrid(
                Item('model.username',
                     tooltip='The username to use when logging in.',
                     editor=TextEditor(invalid='_username_error')),
                Item(
                    'username_icon',
                    editor=ImageEditor(),
                    show_label=False,
                    visible_when='_username_error',
                    tooltip='User name must not be empty.',
                ),
                Item('model.password',
                     tooltip='The password to use when logging in.',
                     editor=TextEditor(
                         invalid='_password_strength_error',
                         password=True,
                     )),
                Item(
                    'password_strength_icon',
                    editor=ImageEditor(),
                    show_label=False,
                ),
                Item('password',
                     label='Re-enter Password:'******'Enter the password a second time.',
                     editor=TextEditor(
                         invalid='_password_match_error',
                         password=True,
                     )),
                Item(
                    'password_match_icon',
                    editor=ImageEditor(),
                    show_label=False,
                    visible_when='_password_match_error',
                    tooltip='Passwords must match.',
                ),
                columns=2,
                show_border=True,
            ),
        ),
        title='Create User Account',
        buttons=OKCancelButtons,
        width=480,
        height=280,
    )
Ejemplo n.º 17
0
class SwiftConsole(HasTraits):
    """Traits-defined Swift Console.

    link : object
      Serial driver
    update : bool
      Update the firmware
    log_level_filter : str
      Syslog string, one of "ERROR", "WARNING", "INFO", "DEBUG".
    """

    link = Instance(sbpc.Handler)
    console_output = Instance(OutputList())
    python_console_env = Dict
    device_serial = Str('')
    dev_id = Str('')
    tracking_view = Instance(TrackingView)
    solution_view = Instance(SolutionView)
    baseline_view = Instance(BaselineView)
    skyplot_view = Instance(SkyplotView)
    observation_view = Instance(ObservationView)
    networking_view = Instance(SbpRelayView)
    observation_view_base = Instance(ObservationView)
    system_monitor_view = Instance(SystemMonitorView)
    settings_view = Instance(SettingsView)
    update_view = Instance(UpdateView)
    imu_view = Instance(IMUView)
    mag_view = Instance(MagView)
    spectrum_analyzer_view = Instance(SpectrumAnalyzerView)
    log_level_filter = Enum(list(SYSLOG_LEVELS.values()))
    """"
  mode : baseline and solution view - SPP, Fixed or Float
  num_sat : baseline and solution view - number of satellites
  port : which port is Swift Device is connected to
  directory_name : location of logged files
  json_logging : enable JSON logging
  csv_logging : enable CSV logging

  """

    mode = Str('')
    ins_status_string = Str('')
    num_sats_str = Str('')
    cnx_desc = Str('')
    age_of_corrections = Str('')
    uuid = Str('')
    directory_name = Directory
    json_logging = Bool(True)
    csv_logging = Bool(False)
    cnx_icon = Str('')
    heartbeat_count = Int()
    last_timer_heartbeat = Int()
    driver_data_rate = Str()
    solid_connection = Bool(False)

    csv_logging_button = SVGButton(
        toggle=True,
        label='CSV log',
        tooltip='start CSV logging',
        toggle_tooltip='stop CSV logging',
        filename=resource_filename('console/images/iconic/pause.svg'),
        toggle_filename=resource_filename('console/images/iconic/play.svg'),
        orientation='vertical',
        width=2,
        height=2, )
    json_logging_button = SVGButton(
        toggle=True,
        label='JSON log',
        tooltip='start JSON logging',
        toggle_tooltip='stop JSON logging',
        filename=resource_filename('console/images/iconic/pause.svg'),
        toggle_filename=resource_filename('console/images/iconic/play.svg'),
        orientation='vertical',
        width=2,
        height=2, )
    paused_button = SVGButton(
        label='',
        tooltip='Pause console update',
        toggle_tooltip='Resume console update',
        toggle=True,
        filename=resource_filename('console/images/iconic/pause.svg'),
        toggle_filename=resource_filename('console/images/iconic/play.svg'),
        width=8,
        height=8)
    clear_button = SVGButton(
        label='',
        tooltip='Clear console buffer',
        filename=resource_filename('console/images/iconic/x.svg'),
        width=8,
        height=8)

    view = View(
        VSplit(
            Tabbed(
                Tabbed(
                    Item('tracking_view', style='custom', label='Signals', show_label=False),
                    Item('skyplot_view', style='custom', label='Sky Plot', show_label=False),
                    label="Tracking"),
                Item('solution_view', style='custom', label='Solution'),
                Item('baseline_view', style='custom', label='Baseline'),
                VSplit(
                    Item('observation_view', style='custom', show_label=False),
                    Item(
                        'observation_view_base',
                        style='custom',
                        show_label=False),
                    label='Observations', ),
                Item('settings_view', style='custom', label='Settings'),
                Item('update_view', style='custom', label='Update'),
                Tabbed(
                    Item(
                        'system_monitor_view',
                        style='custom',
                        label='System Monitor'),
                    Item('imu_view', style='custom', label='IMU'),
                    Item('mag_view', style='custom', label='Magnetometer'),
                    Item(
                        'networking_view',
                        label='Networking',
                        style='custom',
                        show_label=False),
                    Item(
                        'spectrum_analyzer_view',
                        label='Spectrum Analyzer',
                        style='custom'),
                    label='Advanced',
                    show_labels=False),
                show_labels=False),
            VGroup(
                VGroup(
                    HGroup(
                        Spring(width=4, springy=False),
                        Item(
                            'paused_button',
                            show_label=False,
                            padding=0,
                            width=8,
                            height=8),
                        Item(
                            'clear_button',
                            show_label=False,
                            width=8,
                            height=8),
                        Item('', label='Console Log', emphasized=True),
                        Item(
                            'csv_logging_button',
                            emphasized=True,
                            show_label=False,
                            width=12,
                            height=-30,
                            padding=0),
                        Item(
                            'json_logging_button',
                            emphasized=True,
                            show_label=False,
                            width=12,
                            height=-30,
                            padding=0),
                        Item(
                            'directory_name',
                            show_label=False,
                            springy=True,
                            tooltip='Choose location for file logs. Default is home/SwiftNav.',
                            height=-25,
                            enabled_when='not(json_logging or csv_logging)',
                            editor_args={'auto_set': True}),
                        UItem(
                            'log_level_filter',
                            style='simple',
                            padding=0,
                            height=8,
                            show_label=True,
                            tooltip='Show log levels up to and including the selected level of severity.\nThe CONSOLE log level is always visible.'
                        ), ),
                    Item(
                        'console_output',
                        style='custom',
                        editor=InstanceEditor(),
                        height=125,
                        show_label=False,
                        full_size=True), ),
                HGroup(
                    Spring(width=4, springy=False),
                    Item(
                        '',
                        label='Interface:',
                        emphasized=True,
                        tooltip='Interface for communicating with Swift device'
                    ),
                    Item('cnx_desc', show_label=False, style='readonly'),
                    Item(
                        '',
                        label='FIX TYPE:',
                        emphasized=True,
                        tooltip='Device Mode: SPS, Float RTK, Fixed RTK'),
                    Item('mode', show_label=False, style='readonly'),
                    Item(
                        '',
                        label='#Sats:',
                        emphasized=True,
                        tooltip='Number of satellites used in solution'),
                    Item(
                        'num_sats_str',
                        padding=2,
                        show_label=False,
                        style='readonly'),
                    Item(
                        '',
                        label='Corr Age:',
                        emphasized=True,
                        tooltip='Age of corrections (-- means invalid / not present)'
                    ),
                    Item(
                        'age_of_corrections',
                        padding=2,
                        show_label=False,
                        style='readonly'),
                    Item(
                        '',
                        label='INS Status:',
                        emphasized=True,
                        tooltip='INS Status String'
                    ), Item(
                        'ins_status_string',
                        padding=2,
                        show_label=False,
                        style='readonly', width=6),
                    Spring(springy=True),
                    Item('driver_data_rate',
                         style='readonly',
                         show_label=False),
                    Item(
                        'cnx_icon',
                        show_label=False,
                        padding=0,
                        width=8,
                        height=8,
                        visible_when='solid_connection',
                        springy=False,
                        editor=ImageEditor(
                            allow_clipping=False,
                            image=ImageResource(resource_filename('console/images/iconic/arrows_blue.png'))
                        )),
                    Item(
                        'cnx_icon',
                        show_label=False,
                        padding=0,
                        width=8,
                        height=8,
                        visible_when='not solid_connection',
                        springy=False,
                        editor=ImageEditor(
                            allow_clipping=False,
                            image=ImageResource(
                                resource_filename('console/images/iconic/arrows_grey.png')
                            ))),
                    Spring(width=4, height=-2, springy=False), ),
                Spring(height=1, springy=False), ), ),
        icon=icon,
        resizable=True,
        width=800,
        height=600,
        handler=ConsoleHandler(),
        title=CONSOLE_TITLE)

    def print_message_callback(self, sbp_msg, **metadata):
        try:
            encoded = sbp_msg.payload.encode('ascii', 'ignore')
            for eachline in reversed(encoded.split('\n')):
                self.console_output.write_level(
                    eachline, str_to_log_level(eachline.split(':')[0]))
        except UnicodeDecodeError as e:
            print("Error encoding msg_print: {}".format(e))

    def log_message_callback(self, sbp_msg, **metadata):
        encoded = sbp_msg.text.decode('utf8')
        for eachline in reversed(encoded.split('\n')):
            self.console_output.write_level(eachline, sbp_msg.level)

    def ext_event_callback(self, sbp_msg, **metadata):
        e = MsgExtEvent(sbp_msg)
        print(
            'External event: %s edge on pin %d at wn=%d, tow=%d, time qual=%s'
            % ("Rising" if (e.flags & (1 << 0)) else "Falling", e.pin, e.wn,
               e.tow, "good" if (e.flags & (1 << 1)) else "unknown"))

    def cmd_resp_callback(self, sbp_msg, **metadata):
        r = MsgCommandResp(sbp_msg)
        print(
            "Received a command response message with code {0}".format(r.code))

    def _paused_button_fired(self):
        self.console_output.paused = not self.console_output.paused

    def _log_level_filter_changed(self):
        """
        Takes log level enum and translates into the mapped integer.
        Integer stores the current filter value inside OutputList.
        """
        self.console_output.log_level_filter = str_to_log_level(
            self.log_level_filter)

    def _clear_button_fired(self):
        self.console_output.clear()

    def _directory_name_changed(self):
        if self.baseline_view and self.solution_view:
            self.baseline_view.directory_name_b = self.directory_name
            self.solution_view.directory_name_p = self.directory_name
            self.solution_view.directory_name_v = self.directory_name
        if self.observation_view and self.observation_view_base:
            self.observation_view.dirname = self.directory_name
            self.observation_view_base.dirname = self.directory_name

    def check_heartbeat(self):
        # if our heartbeat hasn't changed since the last timer interval the connection must have dropped
        if self.heartbeat_count == self.last_timer_heartbeat:
            self.solid_connection = False
            self.ins_status_string = "None"
            self.mode = "None"
            self.num_sats_str = EMPTY_STR
        else:
            self.solid_connection = True
        self.last_timer_heartbeat = self.heartbeat_count
        total_bytes = self.driver.total_bytes_read
        self.driver_data_rate = "{0:.2f} KB/s".format((total_bytes - self.last_driver_bytes_read) / (1.2 * 1024))
        self.last_driver_bytes_read = total_bytes

    def update_on_heartbeat(self, sbp_msg, **metadata):
        self.heartbeat_count += 1

        # --- determining which mode, llh or baseline, to show in the status bar ---
        llh_display_mode = "None"
        llh_num_sats = 0
        llh_is_differential = False

        baseline_display_mode = "None"
        baseline_num_sats = 0
        baseline_is_differential = False

        # determine the latest llh solution mode
        if self.solution_view:
            llh_solution_mode = self.solution_view.last_pos_mode
            llh_display_mode = mode_dict.get(llh_solution_mode, EMPTY_STR)
            if llh_solution_mode > 0 and self.solution_view.last_soln:
                llh_num_sats = self.solution_view.last_soln.n_sats
            llh_is_differential = (llh_solution_mode in DIFFERENTIAL_MODES)
            if getattr(self.solution_view, 'ins_used', False) and llh_solution_mode != DR_MODE:
                llh_display_mode += "+INS"

        # determine the latest baseline solution mode
        if self.baseline_view and self.settings_view and self.settings_view.dgnss_enabled():
            baseline_solution_mode = self.baseline_view.last_mode
            baseline_display_mode = mode_dict.get(baseline_solution_mode, EMPTY_STR)
            if baseline_solution_mode > 0 and self.baseline_view.last_soln:
                baseline_num_sats = self.baseline_view.last_soln.n_sats
            baseline_is_differential = (baseline_solution_mode in DIFFERENTIAL_MODES)

        # determine the latest INS mode
        if self.solution_view and (monotonic() -
                                   self.solution_view.last_ins_status_receipt_time) < 1:
            ins_flags = self.solution_view.ins_status_flags
            ins_mode = ins_flags & 0x7
            ins_type = (ins_flags >> 29) & 0x7
            odo_status = (ins_flags >> 8) & 0x3
            ins_error = (ins_flags >> 4) & 0xF
            if ins_error != 0:
                ins_status_string = ins_error_dict.get(ins_error, "Unk Error")
            else:
                ins_status_string = ins_type_dict.get(ins_type, "unk") + "-"
                ins_status_string += ins_mode_dict.get(ins_mode, "unk")
                if odo_status == 1:
                    ins_status_string += "+Odo"
            self.ins_status_string = ins_status_string

        # select the solution mode displayed in the status bar:
        # * baseline if it's a differential solution but llh isn't
        # * otherwise llh (also if there is no solution, in which both are "None")
        if baseline_is_differential and not(llh_is_differential):
            self.mode = baseline_display_mode
            self.num_sats_str = "{}".format(baseline_num_sats)
        else:
            self.mode = llh_display_mode
            self.num_sats_str = "{}".format(llh_num_sats)

        # --- end of status bar mode determination section ---

        if self.settings_view:  # for auto populating surveyed fields
            self.settings_view.lat = self.solution_view.latitude
            self.settings_view.lon = self.solution_view.longitude
            self.settings_view.alt = self.solution_view.altitude
        if self.baseline_view:
            if self.baseline_view.age_corrections is not None:
                self.age_of_corrections = "{0} s".format(
                    self.baseline_view.age_corrections)
            else:
                self.age_of_corrections = EMPTY_STR

    def _csv_logging_button_action(self):
        if self.csv_logging and self.baseline_view.logging_b and self.solution_view.logging_p and self.solution_view.logging_v:
            print("Stopped CSV logging")
            self.csv_logging = False
            self.baseline_view.logging_b = False
            self.solution_view.logging_p = False
            self.solution_view.logging_v = False

        else:
            print("Started CSV logging at %s" % self.directory_name)
            self.csv_logging = True
            self.baseline_view.logging_b = True
            self.solution_view.logging_p = True
            self.solution_view.logging_v = True

    def _start_json_logging(self, override_filename=None):
        if override_filename:
            filename = override_filename
        else:
            filename = time.strftime("swift-gnss-%Y%m%d-%H%M%S.sbp.json")
            filename = os.path.normpath(
                os.path.join(self.directory_name, filename))
        self.logger = s.get_logger(True, filename, self.expand_json)
        self.forwarder = sbpc.Forwarder(self.link, self.logger)
        self.forwarder.start()
        if self.settings_view:
            self.settings_view._settings_read_all()

    def _stop_json_logging(self):
        fwd = self.forwarder
        fwd.stop()
        self.logger.flush()
        self.logger.close()

    def _json_logging_button_action(self):
        if self.first_json_press and self.json_logging:
            print(
                "JSON Logging initiated via CMD line.  Please press button again to stop logging"
            )
        elif self.json_logging:
            self._stop_json_logging()
            self.json_logging = False
            print("Stopped JSON logging")
        else:
            self._start_json_logging()
            self.json_logging = True
        self.first_json_press = False

    def _json_logging_button_fired(self):
        if not os.path.exists(self.directory_name) and not self.json_logging:
            confirm_prompt = CallbackPrompt(
                title="Logging directory creation",
                actions=[ok_button],
                callback=self._json_logging_button_action)
            confirm_prompt.text = "\nThe selected logging directory does not exist and will be created."
            confirm_prompt.run(block=False)
        else:
            self._json_logging_button_action()

    def _csv_logging_button_fired(self):
        if not os.path.exists(self.directory_name) and not self.csv_logging:
            confirm_prompt = CallbackPrompt(
                title="Logging directory creation",
                actions=[ok_button],
                callback=self._csv_logging_button_action)
            confirm_prompt.text = "\nThe selected logging directory does not exist and will be created."
            confirm_prompt.run(block=False)
        else:
            self._csv_logging_button_action()

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        self.console_output.close()

    def __init__(self,
                 link,
                 driver,
                 update,
                 log_level_filter,
                 error=False,
                 cnx_desc=None,
                 json_logging=False,
                 log_dirname=None,
                 override_filename=None,
                 log_console=False,
                 connection_info=None,
                 expand_json=False
                 ):
        self.error = error
        self.cnx_desc = cnx_desc
        self.connection_info = connection_info
        self.dev_id = cnx_desc
        self.num_sats_str = EMPTY_STR
        self.mode = ''
        self.ins_status_string = "None"
        self.forwarder = None
        self.age_of_corrections = '--'
        self.expand_json = expand_json
        # if we have passed a logfile, we set our directory to it
        override_filename = override_filename
        self.last_status_update_time = 0
        self.last_driver_bytes_read = 0
        self.driver = driver

        if log_dirname:
            self.directory_name = log_dirname
            if override_filename:
                override_filename = os.path.join(log_dirname,
                                                 override_filename)
        else:
            self.directory_name = swift_path

        # Start swallowing sys.stdout and sys.stderr
        self.console_output = OutputList(
            tfile=log_console, outdir=self.directory_name)
        sys.stdout = self.console_output
        self.console_output.write("Console: " + CONSOLE_VERSION +
                                  " starting...")
        if not error:
            sys.stderr = self.console_output

        self.log_level_filter = log_level_filter
        self.console_output.log_level_filter = str_to_log_level(
            log_level_filter)
        try:
            self.link = link
            self.link.add_callback(self.print_message_callback,
                                   SBP_MSG_PRINT_DEP)
            self.link.add_callback(self.log_message_callback, SBP_MSG_LOG)
            self.link.add_callback(self.ext_event_callback, SBP_MSG_EXT_EVENT)
            self.link.add_callback(self.cmd_resp_callback,
                                   SBP_MSG_COMMAND_RESP)
            self.link.add_callback(self.update_on_heartbeat, SBP_MSG_HEARTBEAT)
            self.dep_handler = DeprecatedMessageHandler(link)
            settings_read_finished_functions = []
            self.tracking_view = TrackingView(self.link)
            self.solution_view = SolutionView(
                self.link, dirname=self.directory_name)
            self.baseline_view = BaselineView(
                self.link, dirname=self.directory_name)
            self.skyplot_view = SkyplotView(self.link, self.tracking_view)
            self.observation_view = ObservationView(
                self.link,
                name='Local',
                relay=False,
                dirname=self.directory_name,
                tracking_view=self.tracking_view)
            self.observation_view_base = ObservationView(
                self.link,
                name='Remote',
                relay=True,
                dirname=self.directory_name)
            self.system_monitor_view = SystemMonitorView(self.link)
            self.update_view = UpdateView(
                self.link,
                download_dir=swift_path,
                prompt=update,
                connection_info=self.connection_info)
            self.imu_view = IMUView(self.link)
            self.mag_view = MagView(self.link)
            self.spectrum_analyzer_view = SpectrumAnalyzerView(self.link)
            settings_read_finished_functions.append(
                self.update_view.compare_versions)
            self.networking_view = SbpRelayView(self.link)
            self.json_logging = json_logging
            self.csv_logging = False
            self.first_json_press = True
            if json_logging:
                self._start_json_logging(override_filename)
                self.json_logging = True
            # we set timer interval to 1200 milliseconds because we expect a heartbeat each second
            self.timer_cancel = call_repeatedly(1.2, self.check_heartbeat)

            # Once we have received the settings, update device_serial with
            # the Swift serial number which will be displayed in the window
            # title. This callback will also update the header route as used
            # by the networking view.

            def update_serial():
                mfg_id = None
                try:
                    self.uuid = self.settings_view.settings['system_info'][
                        'uuid'].value
                    mfg_id = self.settings_view.settings['system_info'][
                        'serial_number'].value
                except KeyError:
                    pass
                if mfg_id:
                    self.device_serial = 'PK' + str(mfg_id)

            skip_settings_read = False
            if 'mode' in self.connection_info:
                if self.connection_info['mode'] == 'file':
                    skip_settings_read = True

            settings_read_finished_functions.append(update_serial)
            self.settings_view = SettingsView(
                self.link,
                settings_read_finished_functions,
                skip_read=skip_settings_read)
            self.update_view.settings = self.settings_view.settings
            self.python_console_env = {
                'send_message': self.link,
                'link': self.link,
            }
            self.python_console_env.update(
                self.tracking_view.python_console_cmds)
            self.python_console_env.update(
                self.solution_view.python_console_cmds)
            self.python_console_env.update(
                self.baseline_view.python_console_cmds)
            self.python_console_env.update(
                self.skyplot_view.python_console_cmds)
            self.python_console_env.update(
                self.observation_view.python_console_cmds)
            self.python_console_env.update(
                self.networking_view.python_console_cmds)
            self.python_console_env.update(
                self.system_monitor_view.python_console_cmds)
            self.python_console_env.update(
                self.update_view.python_console_cmds)
            self.python_console_env.update(self.imu_view.python_console_cmds)
            self.python_console_env.update(self.mag_view.python_console_cmds)
            self.python_console_env.update(
                self.settings_view.python_console_cmds)
            self.python_console_env.update(
                self.spectrum_analyzer_view.python_console_cmds)

        except:  # noqa
            import traceback
            traceback.print_exc()
            if self.error:
                os._exit(1)
Ejemplo n.º 18
0
class Visualization(HasTraits):
    logo = []
    # start_pause_update = Button()
    check_cargo_thread = Instance(CheckCargoThread)
    # active_update = False
    update_scene_thread = Instance(UpdateSceneThread)
    # update_display_thread = Instance(UpdateDisplayThread)
    scene = Instance(MlabSceneModel, ())
    display = Instance(TextDisplay, ())
    log = Instance(LogDisplay, ())

    plots = []
    idx = [-1, 0]                   # idx = [curr_idx, next_idx]

    def __init__(self, display=None):
        # Do not forget to call the parent's __init__
        HasTraits.__init__(self)
        if display:
            self.display = display
        self.check_cargo_thread = CheckCargoThread(self.idx)
        # self.check_cargo_thread.idx = self.idx
        self.check_cargo_thread.wants_abort = False
        self.check_cargo_thread.start()

        self.update_scene_thread = UpdateSceneThread(self.idx)
        self.update_scene_thread.wants_abort = False
        self.update_scene_thread.scene = self.scene
        self.update_scene_thread.plots = self.plots
        self.update_scene_thread.display = self.display
        self.update_scene_thread.log = self.log
        self.update_scene_thread.start()
        # self.active_update = True


    def do_start_pause_update(self):
        if self.check_cargo_thread and not self.check_cargo_thread.isAlive():
            return
        if self.update_scene_thread and self.update_scene_thread.isAlive():
            self.plots = self.update_scene_thread.plots
            self.update_scene_thread.wants_abort = True
            self.log.update('Active update is off!\n')
        else:
            self.update_scene_thread = UpdateSceneThread(self.idx)
            self.update_scene_thread.wants_abort = False
            self.update_scene_thread.scene = self.scene
            self.update_scene_thread.plots = self.plots
            self.update_scene_thread.display = self.display
            self.update_scene_thread.log = self.log
            self.update_scene_thread.start()
            self.log.update('Active update is on!\n')

    def do_stop_all_threading(self):
        if self.check_cargo_thread:
            self.check_cargo_thread.wants_abort = True
        if self.update_scene_thread:
            self.update_scene_thread.wants_abort = True
        self.log.update('All threading stopped!\n')


    def do_prev_cargo(self):
        if self.check_cargo_thread and not self.check_cargo_thread.isAlive():
            return
        if self.update_scene_thread.isAlive():
            self.log.update('Still in Active!  Please pause first!\n')
            return
        else:
            if self.idx[0] == 0:
                self.log.update('Have reached the first cargo!\n')
                return
            else:
                self.idx[0] -= 1
        # self.update_scene()
        self.log.update('Change to Cargo ' + str(self.idx[0]+1) + " (" + str(
            self.idx[1]) + "). \nClick 'Refresh' to start plot\n")
        # self.update_scene_thread.updateOne()
        return

    def do_next_cargo(self):
        if self.check_cargo_thread and not self.check_cargo_thread.isAlive():
            return
        if self.update_scene_thread.isAlive():
            self.log.update('Still in Active!  Please pause first!\n')
            return
        else:
            if self.idx[0] == self.idx[1]-1:
                self.log.update('Have reached the last cargo!\n')
                return
            else:
                self.idx[0] += 1
        # self.update_scene()
        self.log.update('Change to Cargo ' + str(self.idx[0]+1) + " (" + str(
            self.idx[1]) + "). \nClick 'Refresh' to start plot\n")
        # self.update_scene_thread.updateOne()
        return

    def do_refresh_scene(self):
        if self.check_cargo_thread and not self.check_cargo_thread.isAlive():
            return
        if self.update_scene_thread.isAlive():
            self.log.update('Still in Active!  Please pause first!\n')
            return
        self.update_scene_thread.updateOne()
        return

    def do_prev_cargo_show(self):
        if self.check_cargo_thread and not self.check_cargo_thread.isAlive():
            return
        if self.update_scene_thread.isAlive():
            self.log.update('Still in Active!  Please pause first!\n')
            return
        else:
            if self.idx[0] == 0:
                self.log.update('Have reached the first cargo!\n')
                return
            else:
                self.idx[0] -= 1
        # self.update_scene()
        self.do_refresh_scene()
        return

    def do_next_cargo_show(self):
        if self.check_cargo_thread and not self.check_cargo_thread.isAlive():
            return
        if self.update_scene_thread.isAlive():
            self.log.update('Still in Active!  Please pause first!\n')
            return
        else:
            if self.idx[0] == self.idx[1]-1:
                self.log.update('Have reached the last cargo!\n')
                return
            else:
                self.idx[0] += 1
        # self.update_scene()
        self.do_refresh_scene()
        return

    def do_restart(self):
        self.do_stop_all_threading()
        time.sleep(1)
        self.idx = [-1, 0]
        self.plots = []
        self.check_cargo_thread = CheckCargoThread(self.idx)
        self.check_cargo_thread.wants_abort = False
        self.check_cargo_thread.start()

        self.update_scene_thread = UpdateSceneThread(self.idx)
        self.update_scene_thread.wants_abort = False
        self.update_scene_thread.scene = self.scene
        self.update_scene_thread.plots = self.plots
        self.update_scene_thread.display = self.display
        self.update_scene_thread.log = self.log
        self.update_scene_thread.start()

        self.log.update('Threading restarted!\n')

    def do_close(self):
        self.do_stop_all_threading()


    start_pause_update = Action(name="Start/Pause", action="do_start_pause_update")
    stop_all_threading = Action(name="Terminate", action="do_stop_all_threading")
    prev_cargo = Action(name="Prev Cargo", action="do_prev_cargo")
    next_cargo = Action(name="Next Cargo", action="do_next_cargo")
    refresh_scene = Action(name="Refresh", action="do_refresh_scene")
    prev_cargo_show = Action(name="Show Prev", action="do_prev_cargo_show")
    next_cargo_show = Action(name="Show Next", action="do_next_cargo_show")
    close_button = Action(name="Close", action="do_close")
    restart = Action(name='Restart', action='do_restart')

    view = View(
        Group(
            HGroup(
                Item('logo',
                     editor=ImageEditor(scale=True, image=ImageResource('panasonic-logo-small', search_path=['./res'])),
                     show_label=False),
                Item('logo', editor=ImageEditor(scale=True, image=ImageResource('umsjtu-logo', search_path=['./res'])),
                     show_label=False),
                # orientation='horizontal'
            ),
            HGroup(
                Item('scene', editor=SceneEditor(scene_class=MayaviScene), height=500, width=500, show_label=False),
                Group(
                    Item('log', style='custom', height=60, show_label=False),
                    Item('display', style='custom', height=60, show_label=False),
                ),

                # orientation='horizontal'
                # Item('start_pause_update', show_label=False),
                # Item('last_cargo', show_label=False),
                # Item('next_cargo', show_label=False),
                # Item('text', show_label=False, springy=True, height=100, style='custom'),
            ),
            orientation='vertical'
        ),
        buttons=[refresh_scene, prev_cargo, next_cargo, prev_cargo_show, next_cargo_show, start_pause_update, restart, stop_all_threading],
        )

    def __del__(self):
        # print "END"
        if self.check_cargo_thread:
            self.check_cargo_thread.wants_abort = True
        if self.update_scene_thread:
            self.update_scene_thread.wants_abort = True
Ejemplo n.º 19
0
class ImageView(ModelView):
    """A model view of an image with actions.
    """

    #: The image model being viewed.
    model = Instance(ImageModel, (), allow_none=False)

    #: The image to display.
    image = Image()

    def rotate_left(self):
        """Rotate the image anticlockwise."""
        self.model.rotate("anticlockwise")

    def rotate_right(self):
        """Rotate the image clockwise."""
        self.model.rotate("clockwise")

    def flip_horizontal(self):
        """Flip the image horizontally."""
        self.model.flip("horizontal")

    def flip_vertical(self):
        """Flip the image vertically."""
        self.model.flip("vertical")

    def reload(self):
        """Reload the image from disk."""
        self.model.load_image()

    @observe('model.data')
    def _update_image(self, event):
        self.image = ArrayImage(data=self.model.data)

    def _image_default(self):
        return ArrayImage(data=self.model.data)

    view = View(
        HSplit(
            Item(
                'model.image_path',
                editor=FileEditor(
                    dialog_style='open',
                    filter=["*.png", "*.jpg", "*.jpeg"]
                ),
                style='custom',
            ),
            Item(
                'image',
                editor=ImageEditor(
                    scale=True,
                    preserve_aspect_ratio=True,
                    allow_upscaling=True,
                ),
                springy=True,
                resizable=True,
            ),
            show_labels=False,
            # NOTE: this id means the position of the sash will be saved
            id='viewer_split'
        ),
        resizable=True,
        toolbar=ToolBar(
            ActionGroup(
                Action(
                    name="Rotate Left",
                    tooltip="Rotate Left",
                    action='rotate_left',
                    image='rotate_left',
                ),
                Action(
                    name="Rotate Right",
                    tooltip="Rotate Right",
                    action='rotate_right',
                    image='rotate_right',
                ),
                Action(
                    name="Flip Horizontally",
                    tooltip="Flip Horizontally",
                    action='flip_horizontal',
                    image='flip_horizontal',
                ),
                Action(
                    name="Flip Vertically",
                    tooltip="Flip Vertically",
                    action='flip_vertical',
                    image='flip_vertical',
                ),
                name="Transpose Group",
                id="transpose_group",
            ),
            ActionGroup(
                Action(
                    name="Denoise",
                    tooltip="Denoise",
                    action='denoise',
                    image='denoise',
                ),
                name="Filter Group",
                id="filter_group",
            ),
            image_size=(24, 24),
            show_tool_names=False,
        ),
        menubar=MenuBar(
            Menu(
                Action(name="Revert Image", action="revert"),
                name="File",
                id="file_menu",
            ),
            Menu(
                ActionGroup(
                    Action(name="Rotate Left", action='rotate_left'),
                    Action(name="Rotate Right", action='rotate_right'),
                    Action(name="Flip Horizontally", action='flip_horizontal'),
                    Action(name="Flip Vertically", action='flip_vertical'),
                    name="Transpose Group",
                    id="transpose_group",
                ),
                ActionGroup(
                    Action(name="Denoise", action='denoise'),
                    name="Filter Group",
                    id="filter_group",
                ),
                name="Edit",
                id="edit_menu",
            ),
        ),
        # NOTE: this id means the size of the window will be saved
        id='image_preview',
    )
 def get_view(self):
     return View(UItem('name', editor=ImageEditor(image=self.object)))
Ejemplo n.º 21
0
class SwiftConsole(HasTraits):
    """Traits-defined Swift Console.

    link : object
      Serial driver
    update : bool
      Update the firmware
    log_level_filter : str
      Syslog string, one of "ERROR", "WARNING", "INFO", "DEBUG".
    skip_settings : bool
      Don't read the device settings. Set to False when the console is reading
      from a network connection only.

    """

    link = Instance(sbpc.Handler)
    console_output = Instance(OutputList())
    python_console_env = Dict
    device_serial = Str('')
    dev_id = Str('')
    tracking_view = Instance(TrackingView)
    solution_view = Instance(SolutionView)
    baseline_view = Instance(BaselineView)
    observation_view = Instance(ObservationView)
    networking_view = Instance(SbpRelayView)
    observation_view_base = Instance(ObservationView)
    system_monitor_view = Instance(SystemMonitorView)
    settings_view = Instance(SettingsView)
    update_view = Instance(UpdateView)
    imu_view = Instance(IMUView)
    spectrum_analyzer_view = Instance(SpectrumAnalyzerView)
    log_level_filter = Enum(list(SYSLOG_LEVELS.itervalues()))
    """"
  mode : baseline and solution view - SPP, Fixed or Float
  num_sat : baseline and solution view - number of satellites
  port : which port is Swift Device is connected to
  directory_name : location of logged files
  json_logging : enable JSON logging
  csv_logging : enable CSV logging

  """

    mode = Str('')
    num_sats = Int(0)
    cnx_desc = Str('')
    latency = Str('')
    directory_name = Directory
    json_logging = Bool(True)
    csv_logging = Bool(False)
    cnx_icon = Str('')
    heartbeat_count = Int()
    last_timer_heartbeat = Int()
    solid_connection = Bool(False)

    csv_logging_button = SVGButton(
        toggle=True,
        label='CSV log',
        tooltip='start CSV logging',
        toggle_tooltip='stop CSV logging',
        filename=os.path.join(determine_path(), 'images', 'iconic',
                              'pause.svg'),
        toggle_filename=os.path.join(determine_path(), 'images', 'iconic',
                                     'play.svg'),
        orientation='vertical',
        width=2,
        height=2,
    )
    json_logging_button = SVGButton(
        toggle=True,
        label='JSON log',
        tooltip='start JSON logging',
        toggle_tooltip='stop JSON logging',
        filename=os.path.join(determine_path(), 'images', 'iconic',
                              'pause.svg'),
        toggle_filename=os.path.join(determine_path(), 'images', 'iconic',
                                     'play.svg'),
        orientation='vertical',
        width=2,
        height=2,
    )
    paused_button = SVGButton(label='',
                              tooltip='Pause console update',
                              toggle_tooltip='Resume console update',
                              toggle=True,
                              filename=os.path.join(determine_path(), 'images',
                                                    'iconic', 'pause.svg'),
                              toggle_filename=os.path.join(
                                  determine_path(), 'images', 'iconic',
                                  'play.svg'),
                              width=8,
                              height=8)
    clear_button = SVGButton(label='',
                             tooltip='Clear console buffer',
                             filename=os.path.join(determine_path(), 'images',
                                                   'iconic', 'x.svg'),
                             width=8,
                             height=8)

    view = View(VSplit(
        Tabbed(Item('tracking_view', style='custom', label='Tracking'),
               Item('solution_view', style='custom', label='Solution'),
               Item('baseline_view', style='custom', label='Baseline'),
               VSplit(
                   Item('observation_view', style='custom', show_label=False),
                   Item('observation_view_base',
                        style='custom',
                        show_label=False),
                   label='Observations',
               ),
               Item('settings_view', style='custom', label='Settings'),
               Item('update_view', style='custom', label='Firmware Update'),
               Tabbed(Item('system_monitor_view',
                           style='custom',
                           label='System Monitor'),
                      Item('imu_view', style='custom', label='IMU'),
                      Item('networking_view',
                           label='Networking',
                           style='custom',
                           show_label=False),
                      Item('spectrum_analyzer_view',
                           label='Spectrum Analyzer',
                           style='custom'),
                      Item('python_console_env',
                           style='custom',
                           label='Python Console',
                           editor=ShellEditor()),
                      label='Advanced',
                      show_labels=False),
               show_labels=False),
        VGroup(
            VGroup(
                HGroup(
                    Spring(width=4, springy=False),
                    Item('paused_button',
                         show_label=False,
                         padding=0,
                         width=8,
                         height=8),
                    Item('clear_button', show_label=False, width=8, height=8),
                    Item('', label='Console Log', emphasized=True),
                    Item('csv_logging_button',
                         emphasized=True,
                         show_label=False,
                         width=12,
                         height=-30,
                         padding=0),
                    Item('json_logging_button',
                         emphasized=True,
                         show_label=False,
                         width=12,
                         height=-30,
                         padding=0),
                    Item(
                        'directory_name',
                        show_label=False,
                        springy=True,
                        tooltip=
                        'Choose location for file logs. Default is home/SwiftNav.',
                        height=-25,
                        enabled_when='not(json_logging or csv_logging)',
                        editor_args={'auto_set': True}),
                    UItem(
                        'log_level_filter',
                        style='simple',
                        padding=0,
                        height=8,
                        show_label=True,
                        tooltip=
                        'Show log levels up to and including the selected level of severity.\nThe CONSOLE log level is always visible.'
                    ),
                ),
                Item('console_output',
                     style='custom',
                     editor=InstanceEditor(),
                     height=125,
                     show_label=False,
                     full_size=True),
            ),
            HGroup(
                Spring(width=4, springy=False),
                Item('',
                     label='Interface:',
                     emphasized=True,
                     tooltip='Interface for communicating with Swift device'),
                Item('cnx_desc', show_label=False, style='readonly'),
                Item('',
                     label='FIX TYPE:',
                     emphasized=True,
                     tooltip='Device Mode: SPS, Float RTK, Fixed RTK'),
                Item('mode', show_label=False, style='readonly'),
                Item('',
                     label='#Sats:',
                     emphasized=True,
                     tooltip='Number of satellites used in solution'),
                Item('num_sats', padding=2, show_label=False,
                     style='readonly'),
                Item('',
                     label='Base Latency:',
                     emphasized=True,
                     tooltip='Corrections latency (-1 means no corrections)'),
                Item('latency', padding=2, show_label=False, style='readonly'),
                Spring(springy=True),
                Item('cnx_icon',
                     show_label=False,
                     padding=0,
                     width=8,
                     height=8,
                     visible_when='solid_connection',
                     springy=False,
                     editor=ImageEditor(allow_clipping=False,
                                        image=ImageResource(
                                            'arrows_blue.png',
                                            search_path=[
                                                os.path.join(
                                                    determine_path(), 'images',
                                                    'iconic')
                                            ]))),
                Item('cnx_icon',
                     show_label=False,
                     padding=0,
                     width=8,
                     height=8,
                     visible_when='not solid_connection',
                     springy=False,
                     editor=ImageEditor(allow_clipping=False,
                                        image=ImageResource(
                                            'arrows_grey.png',
                                            search_path=[
                                                os.path.join(
                                                    determine_path(), 'images',
                                                    'iconic')
                                            ]))),
                Spring(width=4, height=-2, springy=False),
            ),
            Spring(height=1, springy=False),
        ),
    ),
                icon=icon,
                resizable=True,
                width=800,
                height=600,
                handler=ConsoleHandler(),
                title=CONSOLE_TITLE)

    def print_message_callback(self, sbp_msg, **metadata):
        try:
            encoded = sbp_msg.payload.encode('ascii', 'ignore')
            for eachline in reversed(encoded.split('\n')):
                self.console_output.write_level(
                    eachline, str_to_log_level(eachline.split(':')[0]))
        except UnicodeDecodeError:
            print("Critical Error encoding the serial stream as ascii.")

    def log_message_callback(self, sbp_msg, **metadata):
        try:
            encoded = sbp_msg.text.encode('ascii', 'ignore')
            for eachline in reversed(encoded.split('\n')):
                self.console_output.write_level(eachline, sbp_msg.level)
        except UnicodeDecodeError:
            print("Critical Error encoding the serial stream as ascii.")

    def ext_event_callback(self, sbp_msg, **metadata):
        e = MsgExtEvent(sbp_msg)
        print(
            'External event: %s edge on pin %d at wn=%d, tow=%d, time qual=%s'
            % ("Rising" if
               (e.flags &
                (1 << 0)) else "Falling", e.pin, e.wn, e.tow, "good" if
               (e.flags & (1 << 1)) else "unknown"))

    def cmd_resp_callback(self, sbp_msg, **metadata):
        r = MsgCommandResp(sbp_msg)
        print("Received a command response message with code {0}".format(
            r.code))

    def _paused_button_fired(self):
        self.console_output.paused = not self.console_output.paused

    def _log_level_filter_changed(self):
        """
        Takes log level enum and translates into the mapped integer.
        Integer stores the current filter value inside OutputList.
        """
        self.console_output.log_level_filter = str_to_log_level(
            self.log_level_filter)

    def _clear_button_fired(self):
        self.console_output.clear()

    def _directory_name_changed(self):
        if self.baseline_view and self.solution_view:
            self.baseline_view.directory_name_b = self.directory_name
            self.solution_view.directory_name_p = self.directory_name
            self.solution_view.directory_name_v = self.directory_name
        if self.observation_view and self.observation_view_base:
            self.observation_view.dirname = self.directory_name
            self.observation_view_base.dirname = self.directory_name

    def check_heartbeat(self):
        # if our heartbeat hasn't changed since the last timer interval the connection must have dropped
        if self.heartbeat_count == self.last_timer_heartbeat:
            self.solid_connection = False
        else:
            self.solid_connection = True
        self.last_timer_heartbeat = self.heartbeat_count

    def update_on_heartbeat(self, sbp_msg, **metadata):
        self.heartbeat_count += 1
        # First initialize the state to nothing, if we can't update, it will be none
        temp_mode = "None"
        temp_num_sats = 0
        view = None
        if self.baseline_view and self.solution_view:
            # If we have a recent baseline update, we use the baseline info
            if time.time() - self.baseline_view.last_btime_update < 10:
                view = self.baseline_view
            # Otherwise, if we have a recent SPP update, we use the SPP
            elif time.time() - self.solution_view.last_stime_update < 10:
                view = self.solution_view
            if view:
                if view.last_soln:
                    # if all is well we update state
                    temp_mode = mode_dict.get(get_mode(view.last_soln),
                                              EMPTY_STR)
                    temp_num_sats = view.last_soln.n_sats

        self.mode = temp_mode
        self.num_sats = temp_num_sats

        if self.settings_view:  # for auto populating surveyed fields
            self.settings_view.lat = self.solution_view.latitude
            self.settings_view.lon = self.solution_view.longitude
            self.settings_view.alt = self.solution_view.altitude
        if self.system_monitor_view:
            if self.system_monitor_view.msg_obs_window_latency_ms != -1:
                self.latency = "{0} ms".format(
                    self.system_monitor_view.msg_obs_window_latency_ms)
            else:
                self.latency = EMPTY_STR

    def _csv_logging_button_action(self):
        if self.csv_logging and self.baseline_view.logging_b and self.solution_view.logging_p and self.solution_view.logging_v:
            print("Stopped CSV logging")
            self.csv_logging = False
            self.baseline_view.logging_b = False
            self.solution_view.logging_p = False
            self.solution_view.logging_v = False

        else:
            print("Started CSV logging at %s" % self.directory_name)
            self.csv_logging = True
            self.baseline_view.logging_b = True
            self.solution_view.logging_p = True
            self.solution_view.logging_v = True

    def _start_json_logging(self, override_filename=None):
        if override_filename:
            filename = override_filename
        else:
            filename = time.strftime("swift-gnss-%Y%m%d-%H%M%S.sbp.json")
            filename = os.path.normpath(
                os.path.join(self.directory_name, filename))
        self.logger = s.get_logger(True, filename)
        self.forwarder = sbpc.Forwarder(self.link, self.logger)
        self.forwarder.start()
        if self.settings_view:
            self.settings_view._settings_read_button_fired()

    def _stop_json_logging(self):
        fwd = self.forwarder
        fwd.stop()
        self.logger.flush()
        self.logger.close()

    def _json_logging_button_action(self):
        if self.first_json_press and self.json_logging:
            print(
                "JSON Logging initiated via CMD line.  Please press button again to stop logging"
            )
        elif self.json_logging:
            self._stop_json_logging()
            self.json_logging = False
            print("Stopped JSON logging")
        else:
            self._start_json_logging()
            self.json_logging = True
        self.first_json_press = False

    def _json_logging_button_fired(self):
        if not os.path.exists(self.directory_name) and not self.json_logging:
            confirm_prompt = CallbackPrompt(
                title="Logging directory creation",
                actions=[ok_button],
                callback=self._json_logging_button_action)
            confirm_prompt.text = "\nThe selected logging directory does not exist and will be created."
            confirm_prompt.run(block=False)
        else:
            self._json_logging_button_action()

    def _csv_logging_button_fired(self):
        if not os.path.exists(self.directory_name) and not self.csv_logging:
            confirm_prompt = CallbackPrompt(
                title="Logging directory creation",
                actions=[ok_button],
                callback=self._csv_logging_button_action)
            confirm_prompt.text = "\nThe selected logging directory does not exist and will be created."
            confirm_prompt.run(block=False)
        else:
            self._csv_logging_button_action()

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        self.console_output.close()

    def __init__(self,
                 link,
                 update,
                 log_level_filter,
                 skip_settings=False,
                 error=False,
                 cnx_desc=None,
                 json_logging=False,
                 log_dirname=None,
                 override_filename=None,
                 log_console=False,
                 networking=None,
                 serial_upgrade=False):
        self.error = error
        self.cnx_desc = cnx_desc
        self.dev_id = cnx_desc
        self.num_sats = 0
        self.mode = ''
        self.forwarder = None
        self.latency = '--'
        # if we have passed a logfile, we set our directory to it
        override_filename = override_filename
        home = expanduser("~")
        swift_path = os.path.normpath(os.path.join(home, 'SwiftNav'))

        if log_dirname:
            self.directory_name = log_dirname
            if override_filename:
                override_filename = os.path.join(log_dirname,
                                                 override_filename)
        else:
            self.directory_name = swift_path

        # Start swallowing sys.stdout and sys.stderr
        self.console_output = OutputList(tfile=log_console,
                                         outdir=self.directory_name)
        sys.stdout = self.console_output
        self.console_output.write("Console: " + CONSOLE_VERSION +
                                  " starting...")
        if not error:
            sys.stderr = self.console_output

        self.log_level_filter = log_level_filter
        self.console_output.log_level_filter = str_to_log_level(
            log_level_filter)
        try:
            self.link = link
            self.link.add_callback(self.print_message_callback,
                                   SBP_MSG_PRINT_DEP)
            self.link.add_callback(self.log_message_callback, SBP_MSG_LOG)
            self.link.add_callback(self.ext_event_callback, SBP_MSG_EXT_EVENT)
            self.link.add_callback(self.cmd_resp_callback,
                                   SBP_MSG_COMMAND_RESP)
            self.link.add_callback(self.update_on_heartbeat, SBP_MSG_HEARTBEAT)
            self.dep_handler = DeprecatedMessageHandler(link)
            settings_read_finished_functions = []
            self.tracking_view = TrackingView(self.link)
            self.solution_view = SolutionView(self.link,
                                              dirname=self.directory_name)
            self.baseline_view = BaselineView(self.link,
                                              dirname=self.directory_name)
            self.observation_view = ObservationView(
                self.link,
                name='Local',
                relay=False,
                dirname=self.directory_name)
            self.observation_view_base = ObservationView(
                self.link,
                name='Remote',
                relay=True,
                dirname=self.directory_name)
            self.system_monitor_view = SystemMonitorView(self.link)
            self.update_view = UpdateView(self.link,
                                          download_dir=swift_path,
                                          prompt=update,
                                          serial_upgrade=serial_upgrade)
            self.imu_view = IMUView(self.link)
            self.spectrum_analyzer_view = SpectrumAnalyzerView(self.link)
            settings_read_finished_functions.append(
                self.update_view.compare_versions)
            if networking:
                import yaml
                try:
                    networking_dict = yaml.load(networking)
                    networking_dict.update({'show_networking': True})
                except yaml.YAMLError:
                    print(
                        "Unable to interpret networking cmdline argument.  It will be ignored."
                    )
                    import traceback
                    print(traceback.format_exc())
                    networking_dict = {'show_networking': True}
            else:
                networking_dict = {}
            networking_dict.update(
                {'whitelist': [SBP_MSG_POS_LLH, SBP_MSG_HEARTBEAT]})
            self.networking_view = SbpRelayView(self.link, **networking_dict)
            self.json_logging = json_logging
            self.csv_logging = False
            self.first_json_press = True
            if json_logging:
                self._start_json_logging(override_filename)
                self.json_logging = True
            # we set timer interval to 1200 milliseconds because we expect a heartbeat each second
            self.timer_cancel = call_repeatedly(1.2, self.check_heartbeat)

            # Once we have received the settings, update device_serial with
            # the Swift serial number which will be displayed in the window
            # title. This callback will also update the header route as used
            # by the networking view.

            def update_serial():
                uuid = None
                mfg_id = None
                try:
                    uuid = self.settings_view.settings['system_info'][
                        'uuid'].value
                    mfg_id = self.settings_view.settings['system_info'][
                        'serial_number'].value
                except KeyError:
                    pass
                if mfg_id:
                    self.device_serial = 'PK' + str(mfg_id)[-6:]
                self.networking_view.set_route(uuid=uuid, serial_id=mfg_id)
                if self.networking_view.connect_when_uuid_received:
                    self.networking_view._connect_rover_fired()

            settings_read_finished_functions.append(update_serial)
            self.settings_view = SettingsView(self.link,
                                              settings_read_finished_functions,
                                              skip=skip_settings)
            self.update_view.settings = self.settings_view.settings
            self.python_console_env = {
                'send_message': self.link,
                'link': self.link,
            }
            self.python_console_env.update(
                self.tracking_view.python_console_cmds)
            self.python_console_env.update(
                self.solution_view.python_console_cmds)
            self.python_console_env.update(
                self.baseline_view.python_console_cmds)
            self.python_console_env.update(
                self.observation_view.python_console_cmds)
            self.python_console_env.update(
                self.networking_view.python_console_cmds)
            self.python_console_env.update(
                self.system_monitor_view.python_console_cmds)
            self.python_console_env.update(
                self.update_view.python_console_cmds)
            self.python_console_env.update(self.imu_view.python_console_cmds)
            self.python_console_env.update(
                self.settings_view.python_console_cmds)
            self.python_console_env.update(
                self.spectrum_analyzer_view.python_console_cmds)

        except:
            import traceback
            traceback.print_exc()
            if self.error:
                sys.exit(1)
Ejemplo n.º 22
0
class WorkflowInfo(HasTraits):

    # -------------------
    # Required Attributes
    # -------------------

    #: Filename for the current workflow (if any)
    workflow_filename = Str()

    #: A list of the loaded plugins
    plugins = List(Plugin)

    #: The factory currently selected in the SetupPane
    selected_factory_name = Str()

    #: An error message for the entire workflow
    error_message = Str()

    # ---------------------
    # Dependent Attributes
    # ---------------------

    #: The force project logo! Stored at images/Force_Logo.png
    image = ImageResource('Force_Logo.png')

    #: Message indicating currently loaded file
    workflow_filename_message = Str()

    #: A list of plugin names
    plugin_names = List(Str)

    # -----------
    #    View
    # -----------

    traits_view = View(
        VGroup(
            horizontal_centre(
                Group(UItem('image',
                            editor=ImageEditor(scale=True,
                                               allow_upscaling=False,
                                               preserve_aspect_ratio=True)),
                      visible_when="selected_factory_name == 'Workflow'")),
            Group(UReadonly('plugin_names',
                            editor=ListStrEditor(editable=False)),
                  show_border=True,
                  label='Available Plugins',
                  visible_when="selected_factory_name not in ['KPI']"),
            Group(
                UReadonly('workflow_filename_message', editor=TextEditor()),
                show_border=True,
                label='Workflow Filename',
            ),
            Group(UReadonly('error_message', editor=TextEditor()),
                  show_border=True,
                  label='Workflow Errors',
                  visible_when="selected_factory_name == 'Workflow'"),
        ))

    # -------------------
    #      Defaults
    # -------------------

    def _plugin_names_default(self):
        return [plugin.name for plugin in self.plugins]

    def _workflow_filename_message_default(self):
        if self.workflow_filename == '':
            return 'No File Loaded'
        return 'Current File: ' + self.workflow_filename
Ejemplo n.º 23
0
class DataSourceWizardView(DataSourceWizard):

    #----------------------------------------------------------------------
    # Private traits
    #----------------------------------------------------------------------

    _top_label = Str('Describe your data')

    _info_text = Str('Array size do not match')

    _array_label = Str('Available arrays')

    _data_type_text = Str("What does your data represents?")

    _lines_text = Str("Connect the points with lines")

    _scalar_data_text = Str("Array giving the value of the scalars")

    _optional_scalar_data_text = Str("Associate scalars with the data points")

    _connectivity_text = Str("Array giving the triangles")

    _vector_data_text = Str("Associate vector components")

    _position_text = Property(depends_on="position_type_")

    _position_text_dict = {
        'explicit': 'Coordinnates of the data points:',
        'orthogonal grid': 'Position of the layers along each axis:',
    }

    def _get__position_text(self):
        return self._position_text_dict.get(self.position_type_, "")

    _shown_help_text = Str

    _data_sources_wrappers = Property(depends_on='data_sources')

    def _get__data_sources_wrappers(self):
        return [
            ArrayColumnWrapper(name=name,
                               shape=repr(self.data_sources[name].shape))
            for name in self._data_sources_names
        ]

    # A traits pointing to the object, to play well with traitsUI
    _self = Instance(DataSourceWizard)

    _suitable_traits_view = Property(depends_on="data_type_")

    def _get__suitable_traits_view(self):
        return "_%s_data_view" % self.data_type_

    ui = Any(False)

    _preview_button = Button(label='Preview structure')

    def __preview_button_fired(self):
        if self.ui:
            self.build_data_source()
            self.preview()

    _ok_button = Button(label='OK')

    def __ok_button_fired(self):
        if self.ui:
            self.ui.dispose()
            self.build_data_source()

    _cancel_button = Button(label='Cancel')

    def __cancel_button_fired(self):
        if self.ui:
            self.ui.dispose()

    _is_ok = Bool

    _is_not_ok = Bool

    def _anytrait_changed(self):
        """ Validates if the OK button is enabled.
        """
        if self.ui:
            self._is_ok = self.check_arrays()
            self._is_not_ok = not self._is_ok

    _preview_window = Instance(PreviewWindow, ())

    _info_image = Instance(ImageResource,
                           ImageLibrary.image_resource('@std:alert16', ))

    #----------------------------------------------------------------------
    # TraitsUI views
    #----------------------------------------------------------------------

    _coordinates_group = \
                        HGroup(
                           Item('position_x', label='x',
                               editor=EnumEditor(name='_data_sources_names',
                                        invalid='_is_not_ok')),
                           Item('position_y', label='y',
                               editor=EnumEditor(name='_data_sources_names',
                                        invalid='_is_not_ok')),
                           Item('position_z', label='z',
                               editor=EnumEditor(name='_data_sources_names',
                                        invalid='_is_not_ok')),
                       )


    _position_group = \
                    Group(
                       Item('position_type'),
                       Group(
                           Item('_position_text', style='readonly',
                                    resizable=False,
                                    show_label=False),
                           _coordinates_group,
                           visible_when='not position_type_=="image data"',
                       ),
                       Group(
                           Item('grid_shape_source_',
                            label='Grid shape',
                            editor=EnumEditor(
                                name='_grid_shape_source_labels',
                                        invalid='_is_not_ok')),
                           HGroup(
                            spring,
                            Item('grid_shape', style='custom',
                                    editor=ArrayEditor(width=-60),
                                    show_label=False),
                           enabled_when='grid_shape_source==""',
                            ),
                           visible_when='position_type_=="image data"',
                       ),
                       label='Position of the data points',
                       show_border=True,
                       show_labels=False,
                   ),


    _connectivity_group = \
                   Group(
                       HGroup(
                         Item('_connectivity_text', style='readonly',
                                resizable=False),
                         spring,
                         Item('connectivity_triangles',
                                editor=EnumEditor(name='_data_sources_names'),
                                show_label=False,
                                ),
                         show_labels=False,
                       ),
                       label='Connectivity information',
                       show_border=True,
                       show_labels=False,
                       enabled_when='position_type_=="explicit"',
                   ),


    _scalar_data_group = \
                   Group(
                       Item('_scalar_data_text', style='readonly',
                           resizable=False,
                           show_label=False),
                       HGroup(
                           spring,
                           Item('scalar_data',
                               editor=EnumEditor(name='_data_sources_names',
                                        invalid='_is_not_ok')),
                           show_labels=False,
                           ),
                       label='Scalar value',
                       show_border=True,
                       show_labels=False,
                   )


    _optional_scalar_data_group = \
                   Group(
                       HGroup(
                       'has_scalar_data',
                       Item('_optional_scalar_data_text',
                            resizable=False,
                            style='readonly'),
                       show_labels=False,
                       ),
                       Item('_scalar_data_text', style='readonly',
                            resizable=False,
                            enabled_when='has_scalar_data',
                           show_label=False),
                       HGroup(
                           spring,
                           Item('scalar_data',
                               editor=EnumEditor(name='_data_sources_names',
                                        invalid='_is_not_ok'),
                               enabled_when='has_scalar_data'),
                           show_labels=False,
                           ),
                       label='Scalar data',
                       show_border=True,
                       show_labels=False,
                   ),


    _vector_data_group = \
                   VGroup(
                       HGroup(
                           Item('vector_u', label='u',
                               editor=EnumEditor(name='_data_sources_names',
                                        invalid='_is_not_ok')),
                           Item('vector_v', label='v',
                               editor=EnumEditor(name='_data_sources_names',
                                        invalid='_is_not_ok')),
                           Item('vector_w', label='w',
                               editor=EnumEditor(name='_data_sources_names',
                                        invalid='_is_not_ok')),
                       ),
                       label='Vector data',
                       show_border=True,
                   ),


    _optional_vector_data_group = \
                   VGroup(
                        HGroup(
                            Item('has_vector_data', show_label=False),
                            Item('_vector_data_text', style='readonly',
                                resizable=False,
                                show_label=False),
                        ),
                       HGroup(
                           Item('vector_u', label='u',
                               editor=EnumEditor(name='_data_sources_names',
                                        invalid='_is_not_ok')),
                           Item('vector_v', label='v',
                               editor=EnumEditor(name='_data_sources_names',
                                        invalid='_is_not_ok')),
                           Item('vector_w', label='w',
                               editor=EnumEditor(name='_data_sources_names',
                                        invalid='_is_not_ok')),
                           enabled_when='has_vector_data',
                       ),
                       label='Vector data',
                       show_border=True,
                   ),


    _array_view = \
                View(
                    Item('_array_label', editor=TitleEditor(),
                        show_label=False),
                    Group(
                    Item('_data_sources_wrappers',
                      editor=TabularEditor(
                          adapter = ArrayColumnAdapter(),
                      ),
                    ),
                    show_border=True,
                    show_labels=False
                ))

    _questions_view = View(
        Item('_top_label', editor=TitleEditor(), show_label=False),
        HGroup(
            Item('_data_type_text', style='readonly', resizable=False),
            spring,
            'data_type',
            spring,
            show_border=True,
            show_labels=False,
        ),
        HGroup(
            Item(
                '_self',
                style='custom',
                editor=InstanceEditor(view_name='_suitable_traits_view'),
            ),
            Group(
                # FIXME: Giving up on context sensitive help
                # because of lack of time.
                #Group(
                #    Item('_shown_help_text', editor=HTMLEditor(),
                #        width=300,
                #        label='Help',
                #        ),
                #    show_labels=False,
                #    label='Help',
                #),
                #Group(
                Item('_preview_button', enabled_when='_is_ok'),
                Item('_preview_window',
                     style='custom',
                     label='Preview structure'),
                show_labels=False,
                #label='Preview structure',
                #),
                #layout='tabbed',
                #dock='tab',
            ),
            show_labels=False,
            show_border=True,
        ),
    )

    _point_data_view = \
                View(Group(
                   Group(_coordinates_group,
                        label='Position of the data points',
                        show_border=True,
                   ),
                   HGroup(
                       'lines',
                       Item('_lines_text', style='readonly',
                                        resizable=False),
                       label='Lines',
                       show_labels=False,
                       show_border=True,
                   ),
                   _optional_scalar_data_group,
                   _optional_vector_data_group,
                   # XXX: hack to have more vertical space
                   Label('\n'),
                   Label('\n'),
                   Label('\n'),
                ))


    _surface_data_view = \
                View(Group(
                   _position_group,
                   _connectivity_group,
                   _optional_scalar_data_group,
                   _optional_vector_data_group,
                ))


    _vector_data_view = \
                View(Group(
                   _vector_data_group,
                   _position_group,
                   _optional_scalar_data_group,
                ))


    _volumetric_data_view = \
                View(Group(
                   _scalar_data_group,
                   _position_group,
                   _optional_vector_data_group,
                ))

    _wizard_view = View(
        Group(
            HGroup(
                Item(
                    '_self',
                    style='custom',
                    show_label=False,
                    editor=InstanceEditor(view='_array_view'),
                    width=0.17,
                ),
                '_',
                Item(
                    '_self',
                    style='custom',
                    show_label=False,
                    editor=InstanceEditor(view='_questions_view'),
                ),
            ),
            HGroup(
                Item('_info_image',
                     editor=ImageEditor(),
                     visible_when="_is_not_ok"),
                Item('_info_text',
                     style='readonly',
                     resizable=False,
                     visible_when="_is_not_ok"),
                spring,
                '_cancel_button',
                Item('_ok_button', enabled_when='_is_ok'),
                show_labels=False,
            ),
        ),
        title='Import arrays',
        resizable=True,
    )

    #----------------------------------------------------------------------
    # Public interface
    #----------------------------------------------------------------------

    def __init__(self, **traits):
        DataSourceFactory.__init__(self, **traits)
        self._self = self

    def view_wizard(self):
        """ Pops up the view of the wizard, and keeps the reference it to
            be able to close it.
        """
        # FIXME: Workaround for traits bug in enabled_when
        self.position_type_
        self.data_type_
        self._suitable_traits_view
        self.grid_shape_source
        self._is_ok
        self.ui = self.edit_traits(view='_wizard_view')

    def preview(self):
        """ Display a preview of the data structure in the preview
            window.
        """
        self._preview_window.clear()
        self._preview_window.add_source(self.data_source)
        data = lambda name: self.data_sources[name]
        g = Glyph()
        g.glyph.glyph_source.glyph_source = \
                    g.glyph.glyph_source.glyph_list[0]
        g.glyph.scale_mode = 'data_scaling_off'
        if not (self.has_vector_data or self.data_type_ == 'vector'):
            g.glyph.glyph_source.glyph_source.glyph_type = 'cross'
            g.actor.property.representation = 'points'
            g.actor.property.point_size = 3.
        self._preview_window.add_module(g)
        if not self.data_type_ in ('point', 'vector') or self.lines:
            s = Surface()
            s.actor.property.opacity = 0.3
            self._preview_window.add_module(s)
        if not self.data_type_ == 'point':
            self._preview_window.add_filter(ExtractEdges())
            s = Surface()
            s.actor.property.opacity = 0.2
            self._preview_window.add_module(s)