<commit_before>"""
The Monitor module.  This module provides a variaty of displays for the user.
"""
from threading import Thread

monitor = None

def set_monitor(mon):
  """
     Start a given monitor

     @param monitor: The monitor to start
     @type monitor: C{Monitor}
  """
  global monitor
  if monitor:
    monitor.stop()
  monitor = mon
  monitor.start()

class Monitor(Thread):
  """
     The monitor abstract super class.  All monitors should either inherit
     this class (and override run) or provide the start/stop interface.
  """

  def __init__(self):
    """
       Initialise the monitor
    """
    Thread.__init__(self)
    self.__stop = False  #: Indicate the stopped status

  def stop(self):
    """
       Stop the monitor
    """
    self.__stop = True

  def stopped(self):
    """
       Indicate if the monitor has been stopped
    """
    return self.__stop

class Stat(Monitor):
  """
     The stat monitor.  This monitor is modelled after the *stat tools (such as
     iostat and netstat)
  """

  def __init__(self, delay=1):
    """
       Initialise the monitor

       @param delay:  How often to display a new line
       @type delay: C{int}
    """
    from time import time
    Monitor.__init__(self)

    self.__delay = delay  #: Delay between line prints
    self.__start = time()  #: The time we started

  def run(self):
    """
       Run the monitor
    """
    from port import Port
    import queue
    from sys import stdout
    import target
    from time import sleep

    count = 20
    options = (False, False, False, False)
    while not self.stopped():
      try:
        if len(queue.config_queue) and Port.configure:
          sleep(self.__delay)
          continue
        count += 1

        old_options = options
        options = (len(queue.ports_queue) != 0, len(target.fetch_builder) != 0,
                len(target.build_builder) != 0 and not Port.fetch_only,
                len(target.install_builder) != 0 and not Port.fetch_only)

        if count > 20 or options != old_options:
          count = 0
          self._print_header(options)

        self._print_line(options)

        stdout.flush()
        sleep(self.__delay)
      except KeyboardInterrupt:
        from exit import terminate
        terminate()

  def set_delay(self, delay):
    """
       Set the delay for displaying a new line

       @param delay: The delay
       @type delay: C{int}
    """
    self.__delay = delay

  @staticmethod
  def _print_header(options):
    """
      Print the header for various columns.

      @param options: Tuple of booleans, indicating which columns to display
      @type options: C{(bool)}
    """
    port_q, fetch_q, build_q, install_q = options

    head = ([], [])

    # Time display
    head[0].append('   TIME   ')
    head[1].append('          ')

    if port_q and not (fetch_q and build_q and install_q):
      head[0].append('      PORT       ')
      head[1].append(' Act Queue Total ')
    else:
      head[0].append('  PORT  ')
      head[1].append('        ')

    if fetch_q:
      head[0].append('      FETCH      ')
      head[1].append(' Act Queue Total ')

    if build_q:
      head[0].append('      BUILD      ')
      head[1].append(' Act Queue Total ')

    if install_q:
      head[0].append('     INSTALL     ')
      head[1].append(' Act Queue Total ')

    print
    print "|".join(head[0])
    if port_q or fetch_q or build_q or install_q:
      print "|".join(head[1])
    print "+".join(['-' * len(i) for i in head[0]])

  def _print_line(self, options):
    """
      Print a line describing the current state of the build.  Various options
      are used to control what is displayed.

      @param options: Tuple of booleans, indicating which columns to display
      @type options: C{(bool)}
      @param start: The initial time to use.
      @type start: C{int}
    """
    import queue
    import target

    from port import port_cache
    from time import time

    offset = time() - self.__start
    secs, mins, hour = offset % 60, offset / 60 % 60, offset / 60 / 60
    port_q, fetch_q, build_q, install_q = options

    line = [" %02i:%02i:%02i " % (hour, mins, secs)]

    if port_q and not (fetch_q and build_q and install_q):
      line.append(" %3i %5i %5i " % (len(queue.ports_queue),
                                      queue.ports_queue.qsize(),
                                      len(port_cache)))
    else:
      line.append(" %6i " % len(port_cache))

    if fetch_q:
      line.append(" %3i %5i %5i " % (len(queue.fetch_queue),
                                      queue.fetch_queue.qsize(),
                                      len(target.fetch_builder)))

    if build_q:
      line.append(" %3i %5i %5i " % (len(queue.build_queue),
                                      queue.build_queue.qsize(),
                                      len(target.build_builder)))

    if install_q:
      line.append(" %3i %5i %5i " % (len(queue.install_queue),
                                      queue.install_queue.qsize(),
                                      len(target.install_builder)))

    print "|".join(line)

class Top(Monitor):
  """
     The top monitor.  This monitor is modelled after the top(1) utility.
  """

  def __init__(self):
    """
       Initialise the top monitor
    """
    from time import time
    Monitor.__init__(self)

    self.__delay = 1
    self.__offset = 0
    self.__start = time()
    self.__stats_new = Statistics()
    self.__stats_old = self.__stats_new

  def run(self):
    """
       Run the top monitor, this is done through the curses.wrapper utility
       function
    """
    from curses import wrapper
    wrapper(self._run)

  def _run(self, stdscr):
    """
       Display various details about the build process

       @param stdscr: The main window
       @type stdscr: C{Window}
    """
    from port import Port
    from queue import config_queue
    from time import sleep

    self.update_header(stdscr, True)
    while not self.stopped():
      try:
        if len(config_queue) and Port.configure:
          sleep(self.__delay)
          continue

        self.__stats_old, self.__stats_new = self.__stats_new, Statistics()

        self.update_header(stdscr)

        stdscr.refresh()
        sleep(self.__delay)
      except KeyboardInterrupt:
        from exit import terminate
        terminate()

  def update_header(self, scr, forced=False):
    """
       Update the header details

       @param scr: The window to display the information on
       @type scr: C{Window}
       @param forced: If we have to update
       @type forced: C{bool}
    """
    from time import strftime
    self.__offset = 0
    self.update_ports(scr, forced)
    self.update_summary(scr, forced)
    self.update_stage(scr, "Fetch", Statistics.fetch, forced)
    #self.update_stage(src, "Config", Statistics.config, forced)
    self.update_stage(scr, "Build", Statistics.build, forced)
    self.update_stage(scr, "Install", Statistics.install, forced)

    offset = self.__stats_new.time() - self.__start
    secs, mins, hours = offset % 60, offset / 60 % 60, offset / 60 / 60 % 60
    days = offset / 60 / 60 / 24
    running = "running %i+%i:%i:%i " % (days, hours, mins, secs)
    running += strftime("%H:%M:%S")
    scr.addstr(0, scr.getmaxyx()[1] - len(running) - 1, running)

  def update_ports(self, scr, forced=False):
    """
       Update the ports details

       @param scr: The window to display the information on
       @type scr: C{Window}
       @param forced: If we have to update
       @type forced: C{bool}
    """
    port_old = self.__stats_old.ports()
    port_new = self.__stats_new.ports()

    if port_old != port_new or forced:
      msg = "port count: %i" % port_new[2]
      if port_new[0]:
        if port_new[1]:
          msg += "; retrieving %i (of %i)" % port_new[:2]
        else:
          msg += "r retrieving %i/%i" % (port_new[0], port_new[3])
      scr.addstr(self.__offset, 0, msg)

    self.__offset += 1

  def update_summary(self, scr, forced=False):
    """
       Update the summary information

       @param scr: The window to display the information on
       @type scr: C{Window}
       @param forced: If we have to update
       @type forced: C{bool}
    """
    summary_old = self.__stats_old.summary()
    summary_new = self.__stats_new.summary()

    ports = sum(summary_new)
    if ports:
      if summary_old != summary_new or forced:
        msg = "%i ports:" % ports
        if summary_new[0]:
          msg += " %i active" % summary_new[0]
          if summary_new[1]:
            msg += ", %i queued" % summary_new[1]
          if summary_new[2]:
            msg += ", %i pending" % summary_new[2]
        scr.addstr(self.__offset, 0, msg)

      self.__offset += 1

  def update_stage(self, scr, stage_name, stats, forced=False):
    """
       Update various stage details

       @param scr: The window to display the information on
       @type scr: C{Window}
       @param stage_name: The stage's name
       @type stage_name: C{str}
       @param stats: A method that returns the stages statistics
       @type stats: C{method}
       @param forced: If we have to update
       @type forced: C{bool}
    """
    stats_old = stats(self.__stats_old)
    stats_new = stats(self.__stats_new)

    if stats_new[0] or stats_new[2]:
      if stats_old != stats_new or forced:
        msg = "%s:" % stage_name
        if stats_new[0]:
          if not stats_new[1]:
            msg += "%i/%i active" % (stats_new[0], stats_new[3])
          else:
            msg += "%i active, %i queued" % stats_new[0:2]
          if stats_new[2]:
            msg += ", %i pending" % stats_new[2]
        elif stats_new[2]:
          msg += " %i pending" % stats_new[2]
        scr.addstr(self.__offset, 0, msg)

      self.__offset += 1

class Statistics(object):
  """
      A collection of statistics abouts various queues, builders and ports
  """

  def __init__(self):
    """
        Collect the statistics
    """
    import queue
    import target

    from port import port_cache
    from time import time

    self.__time = time()
    self.__ports = Statistics.size(queue.ports_queue, port_cache)
    self.__fetch = Statistics.size(queue.fetch_queue, target.fetch_builder)
    #self.__config = Statistics.size(queue.config_queue,target.config_builder)
    self.__build = Statistics.size(queue.build_queue, target.build_builder)
    self.__install = Statistics.size(queue.install_queue,
                                      target.install_builder)
    self.__queues = Statistics.get_queues()

  def ports(self):
    """
        The size statistics on the ports

        @return: A tuple of the sizes (active, queued, total, workers)
        @rtype: C{(int, int, int, int)}
    """
    return self.__ports

  def fetch(self):
    """
        The size statistics on the fetch state

        @return: A tuple of the sizes (active, queued, total, workers)
        @rtype: C{(int, int, int, int)}
    """
    return self.__fetch

  #def config(self):
    #"""
        #The size statistics on the config state

        #@return: A tuple of the sizes (active, queued, total, workers)
        #@rtype: C{(int, int, int, int)}
    #"""
    #return self.__config

  def build(self):
    """
        The size statistics on the build state

        @return: A tuple of the sizes (active, queued, total, workers)
        @rtype: C{(int, int, int, int)}
    """
    return self.__build

  def install(self):
    """
        The size statistics on the install state

        @return: A tuple of the sizes (active, queued, total, workers)
        @rtype: C{(int, int, int, int)}
    """
    return self.__install

  def queues(self):
    """
        The collated active, queue, pending queus for fetch, (config), build
        and install.

        @return: A tuple of the ports in the queues
        @rtype: C{((Port), (Port), (Port))}
    """
    return self.__queues

  def summary(self):
    """
        The lenght of the queues (see above)

        @return: A tuple of the lengths
        @rtype: C{(int, int, int)}
    """
    return tuple([len(i) for i in self.__queues])

  def time(self):
    """
        The time these statistics were collated

        @return: The time
        @rtype: C{int}
    """
    return self.__time

  @staticmethod
  def get_queues():
    """
        Collate ordered information about the ports in various queues
    """
    from target import fetch_builder, build_builder, install_builder
      # and config_builder
    fetch = fetch_builder.stats()
    build = build_builder.stats()
    install = install_builder.stats()

    active = install[0] + build[0] + fetch[0]
    queued = install[1] + build[1] + fetch[1]
    pending = []
    for i in fetch[2] + build[2] + install[2]:
      if i not in active and i not in queued:
        pending.append(i)

    return (tuple(active), tuple(queued), tuple(pending))

  @staticmethod
  def size(queue, builder):
    """
        Collect size information about the given queue and builder

        @param queue: The queue for the stage
        @type queue: C{WorkerQueue}
        @param builder: The builder for the stage
        @type builder: C{StageBuilder}
        @return: The size statistics (active, queue, total, workers)
        @rtype: C{(int, int, int, int)}
    """
    return (len(queue), queue.qsize(), len(builder), queue.pool())
<commit_msg> - Remove double statistics (only new required) [Top]    (Code score: 9.86)<commit_after>"""
The Monitor module.  This module provides a variaty of displays for the user.
"""
from threading import Thread

monitor = None

def set_monitor(mon):
  """
     Start a given monitor

     @param monitor: The monitor to start
     @type monitor: C{Monitor}
  """
  global monitor
  if monitor:
    monitor.stop()
  monitor = mon
  monitor.start()

class Monitor(Thread):
  """
     The monitor abstract super class.  All monitors should either inherit
     this class (and override run) or provide the start/stop interface.
  """

  def __init__(self):
    """
       Initialise the monitor
    """
    Thread.__init__(self)
    self.__stop = False  #: Indicate the stopped status

  def stop(self):
    """
       Stop the monitor
    """
    self.__stop = True

  def stopped(self):
    """
       Indicate if the monitor has been stopped
    """
    return self.__stop

class Stat(Monitor):
  """
     The stat monitor.  This monitor is modelled after the *stat tools (such as
     iostat and netstat)
  """

  def __init__(self, delay=1):
    """
       Initialise the monitor

       @param delay:  How often to display a new line
       @type delay: C{int}
    """
    from time import time
    Monitor.__init__(self)

    self.__delay = delay  #: Delay between line prints
    self.__start = time()  #: The time we started

  def run(self):
    """
       Run the monitor
    """
    from port import Port
    import queue
    from sys import stdout
    import target
    from time import sleep

    count = 20
    options = (False, False, False, False)
    while not self.stopped():
      try:
        if len(queue.config_queue) and Port.configure:
          sleep(self.__delay)
          continue
        count += 1

        old_options = options
        options = (len(queue.ports_queue) != 0, len(target.fetch_builder) != 0,
                len(target.build_builder) != 0 and not Port.fetch_only,
                len(target.install_builder) != 0 and not Port.fetch_only)

        if count > 20 or options != old_options:
          count = 0
          self._print_header(options)

        self._print_line(options)

        stdout.flush()
        sleep(self.__delay)
      except KeyboardInterrupt:
        from exit import terminate
        terminate()

  def set_delay(self, delay):
    """
       Set the delay for displaying a new line

       @param delay: The delay
       @type delay: C{int}
    """
    self.__delay = delay

  @staticmethod
  def _print_header(options):
    """
      Print the header for various columns.

      @param options: Tuple of booleans, indicating which columns to display
      @type options: C{(bool)}
    """
    port_q, fetch_q, build_q, install_q = options

    head = ([], [])

    # Time display
    head[0].append('   TIME   ')
    head[1].append('          ')

    if port_q and not (fetch_q and build_q and install_q):
      head[0].append('      PORT       ')
      head[1].append(' Act Queue Total ')
    else:
      head[0].append('  PORT  ')
      head[1].append('        ')

    if fetch_q:
      head[0].append('      FETCH      ')
      head[1].append(' Act Queue Total ')

    if build_q:
      head[0].append('      BUILD      ')
      head[1].append(' Act Queue Total ')

    if install_q:
      head[0].append('     INSTALL     ')
      head[1].append(' Act Queue Total ')

    print
    print "|".join(head[0])
    if port_q or fetch_q or build_q or install_q:
      print "|".join(head[1])
    print "+".join(['-' * len(i) for i in head[0]])

  def _print_line(self, options):
    """
      Print a line describing the current state of the build.  Various options
      are used to control what is displayed.

      @param options: Tuple of booleans, indicating which columns to display
      @type options: C{(bool)}
      @param start: The initial time to use.
      @type start: C{int}
    """
    import queue
    import target

    from port import port_cache
    from time import time

    offset = time() - self.__start
    secs, mins, hour = offset % 60, offset / 60 % 60, offset / 60 / 60
    port_q, fetch_q, build_q, install_q = options

    line = [" %02i:%02i:%02i " % (hour, mins, secs)]

    if port_q and not (fetch_q and build_q and install_q):
      line.append(" %3i %5i %5i " % (len(queue.ports_queue),
                                      queue.ports_queue.qsize(),
                                      len(port_cache)))
    else:
      line.append(" %6i " % len(port_cache))

    if fetch_q:
      line.append(" %3i %5i %5i " % (len(queue.fetch_queue),
                                      queue.fetch_queue.qsize(),
                                      len(target.fetch_builder)))

    if build_q:
      line.append(" %3i %5i %5i " % (len(queue.build_queue),
                                      queue.build_queue.qsize(),
                                      len(target.build_builder)))

    if install_q:
      line.append(" %3i %5i %5i " % (len(queue.install_queue),
                                      queue.install_queue.qsize(),
                                      len(target.install_builder)))

    print "|".join(line)

class Top(Monitor):
  """
     The top monitor.  This monitor is modelled after the top(1) utility.
  """

  def __init__(self):
    """
       Initialise the top monitor
    """
    from time import time
    Monitor.__init__(self)

    self.__delay = 1
    self.__offset = 0
    self.__start = time()
    self.__stats = Statistics()

  def run(self):
    """
       Run the top monitor, this is done through the curses.wrapper utility
       function
    """
    from curses import wrapper
    wrapper(self._run)

  def _run(self, stdscr):
    """
       Display various details about the build process

       @param stdscr: The main window
       @type stdscr: C{Window}
    """
    from curses import setsyx
    from port import Port
    from queue import config_queue
    from time import sleep

    while not self.stopped():
      try:
        if len(config_queue) and Port.configure:
          sleep(self.__delay)
          continue

        self.__stats = Statistics()

        self.update_header(stdscr)

        stdscr.refresh()
        sleep(self.__delay)
        stdscr.clear()
        setsyx(0, 0)
      except KeyboardInterrupt:
        from exit import terminate
        terminate()

    stdscr.refresh()

  def update_header(self, scr):
    """
       Update the header details

       @param scr: The window to display the information on
       @type scr: C{Window}
    """
    from time import strftime
    self.__offset = 0
    self.update_ports(scr)
    self.update_summary(scr)
    self.update_stage(scr, "Fetch", Statistics.fetch)
    #self.update_stage(src, "Config", Statistics.config)
    self.update_stage(scr, "Build", Statistics.build)
    self.update_stage(scr, "Install", Statistics.install)

    offset = self.__stats.time() - self.__start
    secs, mins, hours = offset % 60, offset / 60 % 60, offset / 60 / 60 % 60
    days = offset / 60 / 60 / 24
    running = "running %i+%i:%i:%i " % (days, hours, mins, secs)
    running += strftime("%H:%M:%S")
    scr.addstr(0, scr.getmaxyx()[1] - len(running) - 1, running)

  def update_ports(self, scr):
    """
       Update the ports details

       @param scr: The window to display the information on
       @type scr: C{Window}
    """
    port_new = self.__stats.ports()

    msg = "port count: %i" % port_new[2]
    if port_new[0]:
      if port_new[1]:
        msg += "; retrieving %i (of %i)" % port_new[:2]
      else:
        msg += "r retrieving %i/%i" % (port_new[0], port_new[3])
    scr.addstr(self.__offset, 0, msg)

    self.__offset += 1

  def update_summary(self, scr):
    """
       Update the summary information

       @param scr: The window to display the information on
       @type scr: C{Window}
    """
    summary_new = self.__stats.summary()

    ports = sum(summary_new)
    if ports:
      msg = "%i ports:" % ports
      if summary_new[0]:
        msg += " %i active" % summary_new[0]
        if summary_new[1]:
          msg += ", %i queued" % summary_new[1]
        if summary_new[2]:
          msg += ", %i pending" % summary_new[2]
      scr.addstr(self.__offset, 0, msg)

      self.__offset += 1

  def update_stage(self, scr, stage_name, stats):
    """
       Update various stage details

       @param scr: The window to display the information on
       @type scr: C{Window}
       @param stage_name: The stage's name
       @type stage_name: C{str}
       @param stats: A method that returns the stages statistics
       @type stats: C{method}
    """
    stats_new = stats(self.__stats)

    if stats_new[0] or stats_new[2]:
      msg = "%s:" % stage_name
      if stats_new[0]:
        if not stats_new[1]:
          msg += "%i/%i active" % (stats_new[0], stats_new[3])
        else:
          msg += "%i active, %i queued" % stats_new[0:2]
        if stats_new[2]:
          msg += ", %i pending" % stats_new[2]
      elif stats_new[2]:
        msg += " %i pending" % stats_new[2]
      scr.addstr(self.__offset, 0, msg)

    self.__offset += 1

class Statistics(object):
  """
      A collection of statistics abouts various queues, builders and ports
  """

  def __init__(self):
    """
        Collect the statistics
    """
    import queue
    import target

    from port import port_cache
    from time import time

    self.__time = time()
    self.__ports = Statistics.size(queue.ports_queue, port_cache)
    self.__fetch = Statistics.size(queue.fetch_queue, target.fetch_builder)
    #self.__config = Statistics.size(queue.config_queue,target.config_builder)
    self.__build = Statistics.size(queue.build_queue, target.build_builder)
    self.__install = Statistics.size(queue.install_queue,
                                      target.install_builder)
    self.__queues = Statistics.get_queues()

  def ports(self):
    """
        The size statistics on the ports

        @return: A tuple of the sizes (active, queued, total, workers)
        @rtype: C{(int, int, int, int)}
    """
    return self.__ports

  def fetch(self):
    """
        The size statistics on the fetch state

        @return: A tuple of the sizes (active, queued, total, workers)
        @rtype: C{(int, int, int, int)}
    """
    return self.__fetch

  #def config(self):
    #"""
        #The size statistics on the config state

        #@return: A tuple of the sizes (active, queued, total, workers)
        #@rtype: C{(int, int, int, int)}
    #"""
    #return self.__config

  def build(self):
    """
        The size statistics on the build state

        @return: A tuple of the sizes (active, queued, total, workers)
        @rtype: C{(int, int, int, int)}
    """
    return self.__build

  def install(self):
    """
        The size statistics on the install state

        @return: A tuple of the sizes (active, queued, total, workers)
        @rtype: C{(int, int, int, int)}
    """
    return self.__install

  def queues(self):
    """
        The collated active, queue, pending queus for fetch, (config), build
        and install.

        @return: A tuple of the ports in the queues
        @rtype: C{((Port), (Port), (Port))}
    """
    return self.__queues

  def summary(self):
    """
        The lenght of the queues (see above)

        @return: A tuple of the lengths
        @rtype: C{(int, int, int)}
    """
    return tuple([len(i) for i in self.__queues])

  def time(self):
    """
        The time these statistics were collated

        @return: The time
        @rtype: C{int}
    """
    return self.__time

  @staticmethod
  def get_queues():
    """
        Collate ordered information about the ports in various queues
    """
    from target import fetch_builder, build_builder, install_builder
      # and config_builder
    fetch = fetch_builder.stats()
    build = build_builder.stats()
    install = install_builder.stats()

    active = install[0] + build[0] + fetch[0]
    queued = install[1] + build[1] + fetch[1]
    pending = []
    for i in fetch[2] + build[2] + install[2]:
      if i not in active and i not in queued:
        pending.append(i)

    return (tuple(active), tuple(queued), tuple(pending))

  @staticmethod
  def size(queue, builder):
    """
        Collect size information about the given queue and builder

        @param queue: The queue for the stage
        @type queue: C{WorkerQueue}
        @param builder: The builder for the stage
        @type builder: C{StageBuilder}
        @return: The size statistics (active, queue, total, workers)
        @rtype: C{(int, int, int, int)}
    """
    return (len(queue), queue.qsize(), len(builder), queue.pool())
<|endoftext|>


<commit_before>"""
The Monitor module.  This module provides a variaty of displays for the user.
"""
from threading import Thread

monitor = None

def set_monitor(mon):
  """
     Start a given monitor

     @param monitor: The monitor to start
     @type monitor: C{Monitor}
  """
  global monitor
  if monitor:
    monitor.stop()
  monitor = mon
  monitor.start()

class Monitor(Thread):
  """
     The monitor abstract super class.  All monitors should either inherit
     this class (and override run) or provide the start/stop interface.
  """

  def __init__(self):
    """
       Initialise the monitor
    """
    Thread.__init__(self)
    self.__stop = False  #: Indicate the stopped status

  def stop(self):
    """
       Stop the monitor
    """
    self.__stop = True

  def stopped(self):
    """
       Indicate if the monitor has been stopped
    """
    return self.__stop

class Stat(Monitor):
  """
     The stat monitor.  This monitor is modelled after the *stat tools (such as
     iostat and netstat)
  """

  def __init__(self, delay=1):
    """
       Initialise the monitor

       @param delay:  How often to display a new line
       @type delay: C{int}
    """
    from time import time
    Monitor.__init__(self)

    self.__delay = delay  #: Delay between line prints
    self.__start = time()  #: The time we started

  def run(self):
    """
       Run the monitor
    """
    from port import Port
    import queue
    from sys import stdout
    import target
    from time import sleep

    count = 20
    options = (False, False, False, False)
    while not self.stopped():
      try:
        if len(queue.config_queue) and Port.configure:
          sleep(self.__delay)
          continue
        count += 1

        old_options = options
        options = (len(queue.ports_queue) != 0, len(target.fetch_builder) != 0,
                len(target.build_builder) != 0 and not Port.fetch_only,
                len(target.install_builder) != 0 and not Port.fetch_only)

        if count > 20 or options != old_options:
          count = 0
          self._print_header(options)

        self._print_line(options)

        stdout.flush()
        sleep(self.__delay)
      except KeyboardInterrupt:
        from exit import terminate
        terminate()

  def set_delay(self, delay):
    """
       Set the delay for displaying a new line

       @param delay: The delay
       @type delay: C{int}
    """
    self.__delay = delay

  @staticmethod
  def _print_header(options):
    """
      Print the header for various columns.

      @param options: Tuple of booleans, indicating which columns to display
      @type options: C{(bool)}
    """
    port_q, fetch_q, build_q, install_q = options

    head = ([], [])

    # Time display
    head[0].append('   TIME   ')
    head[1].append('          ')

    if port_q and not (fetch_q and build_q and install_q):
      head[0].append('      PORT       ')
      head[1].append(' Act Queue Total ')
    else:
      head[0].append('  PORT  ')
      head[1].append('        ')

    if fetch_q:
      head[0].append('      FETCH      ')
      head[1].append(' Act Queue Total ')

    if build_q:
      head[0].append('      BUILD      ')
      head[1].append(' Act Queue Total ')

    if install_q:
      head[0].append('     INSTALL     ')
      head[1].append(' Act Queue Total ')

    print
    print "|".join(head[0])
    if port_q or fetch_q or build_q or install_q:
      print "|".join(head[1])
    print "+".join(['-' * len(i) for i in head[0]])

  def _print_line(self, options):
    """
      Print a line describing the current state of the build.  Various options
      are used to control what is displayed.

      @param options: Tuple of booleans, indicating which columns to display
      @type options: C{(bool)}
      @param start: The initial time to use.
      @type start: C{int}
    """
    import queue
    import target

    from port import port_cache
    from time import time

    offset = time() - self.__start
    secs, mins, hour = offset % 60, offset / 60 % 60, offset / 60 / 60
    port_q, fetch_q, build_q, install_q = options

    line = [" %02i:%02i:%02i " % (hour, mins, secs)]

    if port_q and not (fetch_q and build_q and install_q):
      line.append(" %3i %5i %5i " % (len(queue.ports_queue),
                                      queue.ports_queue.qsize(),
                                      len(port_cache)))
    else:
      line.append(" %6i " % len(port_cache))

    if fetch_q:
      line.append(" %3i %5i %5i " % (len(queue.fetch_queue),
                                      queue.fetch_queue.qsize(),
                                      len(target.fetch_builder)))

    if build_q:
      line.append(" %3i %5i %5i " % (len(queue.build_queue),
                                      queue.build_queue.qsize(),
                                      len(target.build_builder)))

    if install_q:
      line.append(" %3i %5i %5i " % (len(queue.install_queue),
                                      queue.install_queue.qsize(),
                                      len(target.install_builder)))

    print "|".join(line)

class Top(Monitor):
  """
     The top monitor.  This monitor is modelled after the top(1) utility.
  """

  def __init__(self):
    """
       Initialise the top monitor
    """
    from time import time
    Monitor.__init__(self)

    self.__delay = 1
    self.__offset = 0
    self.__start = time()
    self.__stats = Statistics()

  def run(self):
    """
       Run the top monitor, this is done through the curses.wrapper utility
       function
    """
    from curses import wrapper
    wrapper(self._run)

  def _run(self, stdscr):
    """
       Display various details about the build process

       @param stdscr: The main window
       @type stdscr: C{Window}
    """
    from port import Port
    from queue import config_queue
    from time import sleep

    while not self.stopped():
      try:
        if len(config_queue) and Port.configure:
          sleep(self.__delay)
          continue

        self.__stats = Statistics()

        self.update_header(stdscr)
        stdscr.move(self.__offset, 0)

        stdscr.refresh()
        sleep(self.__delay)
        stdscr.erase()
      except KeyboardInterrupt:
        from exit import terminate
        terminate()

    stdscr.erase()
    stdscr.move(0, 0)
    stdscr.refresh()

  def update_header(self, scr):
    """
       Update the header details

       @param scr: The window to display the information on
       @type scr: C{Window}
    """
    from time import strftime
    self.__offset = 0
    self.update_ports(scr)
    self.update_summary(scr)
    self.update_stage(scr, "Fetch", Statistics.fetch)
    #self.update_stage(src, "Config", Statistics.config)
    self.update_stage(scr, "Build", Statistics.build)
    self.update_stage(scr, "Install", Statistics.install)

    offset = self.__stats.time() - self.__start
    secs, mins, hours = offset % 60, offset / 60 % 60, offset / 60 / 60 % 60
    days = offset / 60 / 60 / 24
    running = "running %i+%02i:%02i:%02i  " % (days, hours, mins, secs)
    running += strftime("%H:%M:%S")
    scr.addstr(0, scr.getmaxyx()[1] - len(running) - 1, running)

  def update_ports(self, scr):
    """
       Update the ports details

       @param scr: The window to display the information on
       @type scr: C{Window}
    """
    port_new = self.__stats.ports()

    msg = "port count: %i" % port_new[2]
    if port_new[0]:
      if port_new[1]:
        msg += "; retrieving %i (of %i)" % port_new[:2]
      else:
        msg += "; retrieving %i/%i" % (port_new[0], port_new[3])
    scr.addstr(self.__offset, 0, msg)

    self.__offset += 1

  def update_summary(self, scr):
    """
       Update the summary information

       @param scr: The window to display the information on
       @type scr: C{Window}
    """
    summary_new = self.__stats.summary()

    ports = sum(summary_new)
    if ports:
      msg = "%i ports:" % ports
      if summary_new[0]:
        msg += " %i active" % summary_new[0]
        if summary_new[1]:
          msg += ", %i queued" % summary_new[1]
        if summary_new[2]:
          msg += ", %i pending" % summary_new[2]
      scr.addstr(self.__offset, 0, msg)

      self.__offset += 1

  def update_stage(self, scr, stage_name, stats):
    """
       Update various stage details

       @param scr: The window to display the information on
       @type scr: C{Window}
       @param stage_name: The stage's name
       @type stage_name: C{str}
       @param stats: A method that returns the stages statistics
       @type stats: C{method}
    """
    stats_new = stats(self.__stats)

    if stats_new[0] or stats_new[2]:
      msg = "%s: " % stage_name
      if stats_new[0]:
        if not stats_new[1]:
          msg += "%i/%i active" % (stats_new[0], stats_new[3])
        else:
          msg += "%i active, %i queued" % stats_new[0:2]
        if stats_new[2]:
          msg += ", %i pending" % stats_new[2]
      elif stats_new[2]:
        msg += "%i pending" % stats_new[2]
      scr.addstr(self.__offset, 0, msg)

      self.__offset += 1

class Statistics(object):
  """
      A collection of statistics abouts various queues, builders and ports
  """

  def __init__(self):
    """
        Collect the statistics
    """
    import queue
    import target

    from port import port_cache
    from time import time

    self.__time = time()
    self.__ports = Statistics.size(queue.ports_queue, port_cache)
    self.__fetch = Statistics.size(queue.fetch_queue, target.fetch_builder)
    #self.__config = Statistics.size(queue.config_queue,target.config_builder)
    self.__build = Statistics.size(queue.build_queue, target.build_builder)
    self.__install = Statistics.size(queue.install_queue,
                                      target.install_builder)
    self.__queues = Statistics.get_queues()

  def ports(self):
    """
        The size statistics on the ports

        @return: A tuple of the sizes (active, queued, total, workers)
        @rtype: C{(int, int, int, int)}
    """
    return self.__ports

  def fetch(self):
    """
        The size statistics on the fetch state

        @return: A tuple of the sizes (active, queued, total, workers)
        @rtype: C{(int, int, int, int)}
    """
    return self.__fetch

  #def config(self):
    #"""
        #The size statistics on the config state

        #@return: A tuple of the sizes (active, queued, total, workers)
        #@rtype: C{(int, int, int, int)}
    #"""
    #return self.__config

  def build(self):
    """
        The size statistics on the build state

        @return: A tuple of the sizes (active, queued, total, workers)
        @rtype: C{(int, int, int, int)}
    """
    return self.__build

  def install(self):
    """
        The size statistics on the install state

        @return: A tuple of the sizes (active, queued, total, workers)
        @rtype: C{(int, int, int, int)}
    """
    return self.__install

  def queues(self):
    """
        The collated active, queue, pending queus for fetch, (config), build
        and install.

        @return: A tuple of the ports in the queues
        @rtype: C{((Port), (Port), (Port))}
    """
    return self.__queues

  def summary(self):
    """
        The lenght of the queues (see above)

        @return: A tuple of the lengths
        @rtype: C{(int, int, int)}
    """
    return tuple([len(i) for i in self.__queues])

  def time(self):
    """
        The time these statistics were collated

        @return: The time
        @rtype: C{int}
    """
    return self.__time

  @staticmethod
  def get_queues():
    """
        Collate ordered information about the ports in various queues
    """
    from target import fetch_builder, build_builder, install_builder
      # and config_builder
    fetch = fetch_builder.stats()
    build = build_builder.stats()
    install = install_builder.stats()

    active = install[0] + build[0] + fetch[0]
    queued = install[1] + build[1] + fetch[1]
    pending = []
    for i in fetch[2] + build[2] + install[2]:
      if i not in active and i not in queued:
        pending.append(i)

    return (tuple(active), tuple(queued), tuple(pending))

  @staticmethod
  def size(queue, builder):
    """
        Collect size information about the given queue and builder

        @param queue: The queue for the stage
        @type queue: C{WorkerQueue}
        @param builder: The builder for the stage
        @type builder: C{StageBuilder}
        @return: The size statistics (active, queue, total, workers)
        @rtype: C{(int, int, int, int)}
    """
    return (len(queue), queue.qsize(), len(builder), queue.pool())
<commit_msg> - Add the rest of the monitor [Top]    (Code score: 9.87)<commit_after>"""
The Monitor module.  This module provides a variaty of displays for the user.
"""
from threading import Thread

monitor = None

def set_monitor(mon):
  """
     Start a given monitor

     @param monitor: The monitor to start
     @type monitor: C{Monitor}
  """
  global monitor
  if monitor:
    monitor.stop()
  monitor = mon
  monitor.start()

class Monitor(Thread):
  """
     The monitor abstract super class.  All monitors should either inherit
     this class (and override run) or provide the start/stop interface.
  """

  def __init__(self):
    """
       Initialise the monitor
    """
    Thread.__init__(self)
    self.__stop = False  #: Indicate the stopped status

  def stop(self):
    """
       Stop the monitor
    """
    self.__stop = True

  def stopped(self):
    """
       Indicate if the monitor has been stopped
    """
    return self.__stop

class Stat(Monitor):
  """
     The stat monitor.  This monitor is modelled after the *stat tools (such as
     iostat and netstat)
  """

  def __init__(self, delay=1):
    """
       Initialise the monitor

       @param delay:  How often to display a new line
       @type delay: C{int}
    """
    from time import time
    Monitor.__init__(self)

    self.__delay = delay  #: Delay between line prints
    self.__start = time()  #: The time we started

  def run(self):
    """
       Run the monitor
    """
    from port import Port
    import queue
    from sys import stdout
    import target
    from time import sleep

    count = 20
    options = (False, False, False, False)
    while not self.stopped():
      try:
        if len(queue.config_queue) and Port.configure:
          sleep(self.__delay)
          continue
        count += 1

        old_options = options
        options = (len(queue.ports_queue) != 0, len(target.fetch_builder) != 0,
                len(target.build_builder) != 0 and not Port.fetch_only,
                len(target.install_builder) != 0 and not Port.fetch_only)

        if count > 20 or options != old_options:
          count = 0
          self._print_header(options)

        self._print_line(options)

        stdout.flush()
        sleep(self.__delay)
      except KeyboardInterrupt:
        from exit import terminate
        terminate()

  def set_delay(self, delay):
    """
       Set the delay for displaying a new line

       @param delay: The delay
       @type delay: C{int}
    """
    self.__delay = delay

  @staticmethod
  def _print_header(options):
    """
      Print the header for various columns.

      @param options: Tuple of booleans, indicating which columns to display
      @type options: C{(bool)}
    """
    port_q, fetch_q, build_q, install_q = options

    head = ([], [])

    # Time display
    head[0].append('   TIME   ')
    head[1].append('          ')

    if port_q and not (fetch_q and build_q and install_q):
      head[0].append('      PORT       ')
      head[1].append(' Act Queue Total ')
    else:
      head[0].append('  PORT  ')
      head[1].append('        ')

    if fetch_q:
      head[0].append('      FETCH      ')
      head[1].append(' Act Queue Total ')

    if build_q:
      head[0].append('      BUILD      ')
      head[1].append(' Act Queue Total ')

    if install_q:
      head[0].append('     INSTALL     ')
      head[1].append(' Act Queue Total ')

    print
    print "|".join(head[0])
    if port_q or fetch_q or build_q or install_q:
      print "|".join(head[1])
    print "+".join(['-' * len(i) for i in head[0]])

  def _print_line(self, options):
    """
      Print a line describing the current state of the build.  Various options
      are used to control what is displayed.

      @param options: Tuple of booleans, indicating which columns to display
      @type options: C{(bool)}
      @param start: The initial time to use.
      @type start: C{int}
    """
    import queue
    import target

    from port import port_cache
    from time import time

    offset = time() - self.__start
    secs, mins, hour = offset % 60, offset / 60 % 60, offset / 60 / 60
    port_q, fetch_q, build_q, install_q = options

    line = [" %02i:%02i:%02i " % (hour, mins, secs)]

    if port_q and not (fetch_q and build_q and install_q):
      line.append(" %3i %5i %5i " % (len(queue.ports_queue),
                                      queue.ports_queue.qsize(),
                                      len(port_cache)))
    else:
      line.append(" %6i " % len(port_cache))

    if fetch_q:
      line.append(" %3i %5i %5i " % (len(queue.fetch_queue),
                                      queue.fetch_queue.qsize(),
                                      len(target.fetch_builder)))

    if build_q:
      line.append(" %3i %5i %5i " % (len(queue.build_queue),
                                      queue.build_queue.qsize(),
                                      len(target.build_builder)))

    if install_q:
      line.append(" %3i %5i %5i " % (len(queue.install_queue),
                                      queue.install_queue.qsize(),
                                      len(target.install_builder)))

    print "|".join(line)

class Top(Monitor):
  """
     The top monitor.  This monitor is modelled after the top(1) utility.
  """

  def __init__(self):
    """
       Initialise the top monitor
    """
    from time import time
    Monitor.__init__(self)

    self.__delay = 1
    self.__offset = 0
    self.__start = time()
    self.__stats = Statistics()

  def run(self):
    """
       Run the top monitor, this is done through the curses.wrapper utility
       function
    """
    from curses import wrapper
    wrapper(self._run)

  def _run(self, stdscr):
    """
       Display various details about the build process

       @param stdscr: The main window
       @type stdscr: C{Window}
    """
    from port import Port
    from queue import config_queue
    from time import sleep

    while not self.stopped():
      try:
        if len(config_queue) and Port.configure:
          sleep(self.__delay)
          continue

        self.__stats = Statistics()

        self.update_header(stdscr)
        self.update_rows(stdscr)
        stdscr.move(self.__offset, 0)

        stdscr.refresh()
        sleep(self.__delay)
        stdscr.erase()
      except KeyboardInterrupt:
        from exit import terminate
        terminate()

    stdscr.erase()
    stdscr.move(0, 0)
    stdscr.refresh()

  def update_header(self, scr):
    """
       Update the header details

       @param scr: The window to display the information on
       @type scr: C{Window}
    """
    from time import strftime
    self.__offset = 0
    self.update_ports(scr)
    self.update_summary(scr)
    self.update_stage(scr, "Fetch", Statistics.fetch)
    #self.update_stage(src, "Config", Statistics.config)
    self.update_stage(scr, "Build", Statistics.build)
    self.update_stage(scr, "Install", Statistics.install)

    offset = self.__stats.time() - self.__start
    secs, mins, hours = offset % 60, offset / 60 % 60, offset / 60 / 60 % 60
    days = offset / 60 / 60 / 24
    running = "running %i+%02i:%02i:%02i  " % (days, hours, mins, secs)
    running += strftime("%H:%M:%S")
    scr.addstr(0, scr.getmaxyx()[1] - len(running) - 1, running)

  def update_ports(self, scr):
    """
       Update the ports details

       @param scr: The window to display the information on
       @type scr: C{Window}
    """
    port_new = self.__stats.ports()

    msg = "port count: %i" % port_new[2]
    if port_new[0]:
      if port_new[1]:
        msg += "; retrieving %i (of %i)" % port_new[:2]
      else:
        msg += "; retrieving %i/%i" % (port_new[0], port_new[3])
    scr.addstr(self.__offset, 0, msg)

    self.__offset += 1

  def update_summary(self, scr):
    """
       Update the summary information

       @param scr: The window to display the information on
       @type scr: C{Window}
    """
    summary_new = self.__stats.summary()

    ports = sum(summary_new)
    if ports:
      msg = "%i ports:" % ports
      if summary_new[0]:
        msg += " %i active" % summary_new[0]
        if summary_new[1]:
          msg += ", %i queued" % summary_new[1]
        if summary_new[2]:
          msg += ", %i pending" % summary_new[2]
      scr.addstr(self.__offset, 0, msg)

      self.__offset += 1

  def update_stage(self, scr, stage_name, stats):
    """
       Update various stage details

       @param scr: The window to display the information on
       @type scr: C{Window}
       @param stage_name: The stage's name
       @type stage_name: C{str}
       @param stats: A method that returns the stages statistics
       @type stats: C{method}
    """
    stats = list(stats(self.__stats))
    stats[2] -= stats[0] + stats[1]

    if stats[0] or stats[2]:
      msg = "%s: " % stage_name
      if stats[0]:
        if not stats[1]:
          msg += "%i/%i active" % (stats[0], stats[3])
        else:
          msg += "%i active, %i queued" % tuple(stats[0:2])
        if stats[2]:
          msg += ", %i pending" % stats[2]
      elif stats[2]:
        msg += "%i pending" % stats[2]
      scr.addstr(self.__offset, 0, msg)

      self.__offset += 1

  def update_rows(self, scr):
    """
       Update the rows of port information

       @param scr: The window to display the information on
       @type scr: C{Window}
    """
    def get_stage(port, offset=0):
      """
         Get the ports stage name.  If it is 'install' then abreviate to
         'instal' or if it is 'configure' then abreviate to 'config'

         @param port: The port
         @type port: C{Port}
         @param offset: The stage from this one
         @type offset: C{int}
         @return: The stage's name
         @rtype: C{str}
      """
      from port import Port

      stage = Port.STAGE_NAME[port.stage() + offset]
      if stage[-1] == 'l':
        return stage[:-1]
      if stage.endswith('ure'):
        return stage[:-3]
      return stage

    def get_name(port):
      """
         Get the ports name

         @param port: The port
         @type port: C{Port}
         @return: The name as 'origin (version)'
         @rtype: C{str}
      """
      return '%s (%s)' % (port.origin(), port.attr('pkgname').rsplit('-', 1)[1])

    active, queued, pending = self.__stats.queues()

    scr.addstr(self.__offset + 1, 2, 'PID  STAGE   STATE   TIME PORT (VERSION)')

    lines, columns = scr.getmaxyx()
    lines -= self.__offset + 2
    offset = self.__offset + 2
    for i in range(min(lines, len(active))):
      port = active[i]
      time = port.working()
      if time:
        offtime = self.__stats.time() - time
        time = '%3i:%02i' % (offtime / 60, offtime % 60)
      else:
        time = ' ' * 6
      scr.addnstr(offset + i, 0, '%5i %6s  active %s %s' %
                  (0, get_stage(port), time, get_name(port)), columns)

    lines -= len(active)
    offset += len(active)
    for i in range(min(lines, len(queued))):
      port = queued[i]
      scr.addnstr(offset + i, 0, '%5i %6s  queued        %s' %
                  (0, get_stage(port, 1), get_name(port)), columns)

    lines -= len(queued)
    offset += len(queued)
    for i in range(min(lines, len(pending))):
      port = pending[i]
      scr.addnstr(offset + i, 0, '%5i %6s pending        %s' %
                  (0, get_stage(port, 1), get_name(port)), columns)

class Statistics(object):
  """
      A collection of statistics abouts various queues, builders and ports
  """

  def __init__(self):
    """
        Collect the statistics
    """
    import queue
    import target

    from port import port_cache
    from time import time

    self.__time = time()
    self.__ports = Statistics.size(queue.ports_queue, port_cache)
    self.__fetch = Statistics.size(queue.fetch_queue, target.fetch_builder)
    #self.__config = Statistics.size(queue.config_queue,target.config_builder)
    self.__build = Statistics.size(queue.build_queue, target.build_builder)
    self.__install = Statistics.size(queue.install_queue,
                                      target.install_builder)
    self.__queues = Statistics.get_queues()

  def ports(self):
    """
        The size statistics on the ports

        @return: A tuple of the sizes (active, queued, total, workers)
        @rtype: C{(int, int, int, int)}
    """
    return self.__ports

  def fetch(self):
    """
        The size statistics on the fetch state

        @return: A tuple of the sizes (active, queued, total, workers)
        @rtype: C{(int, int, int, int)}
    """
    return self.__fetch

  #def config(self):
    #"""
        #The size statistics on the config state

        #@return: A tuple of the sizes (active, queued, total, workers)
        #@rtype: C{(int, int, int, int)}
    #"""
    #return self.__config

  def build(self):
    """
        The size statistics on the build state

        @return: A tuple of the sizes (active, queued, total, workers)
        @rtype: C{(int, int, int, int)}
    """
    return self.__build

  def install(self):
    """
        The size statistics on the install state

        @return: A tuple of the sizes (active, queued, total, workers)
        @rtype: C{(int, int, int, int)}
    """
    return self.__install

  def queues(self):
    """
        The collated active, queue, pending queus for fetch, (config), build
        and install.

        @return: A tuple of the ports in the queues
        @rtype: C{((Port), (Port), (Port))}
    """
    return self.__queues

  def summary(self):
    """
        The lenght of the queues (see above)

        @return: A tuple of the lengths
        @rtype: C{(int, int, int)}
    """
    return tuple([len(i) for i in self.__queues])

  def time(self):
    """
        The time these statistics were collated

        @return: The time
        @rtype: C{int}
    """
    return self.__time

  @staticmethod
  def get_queues():
    """
        Collate ordered information about the ports in various queues
    """
    from target import fetch_builder, build_builder, install_builder
      # and config_builder
    fetch = fetch_builder.stats()
    build = build_builder.stats()
    install = install_builder.stats()

    active = install[0] + build[0] + fetch[0]
    queued = install[1] + build[1] + fetch[1]
    pending = []
    for i in fetch[2] + build[2] + install[2]:
      if i not in active and i not in queued:
        pending.append(i)
    pending.reverse()

    return (tuple(active), tuple(queued), tuple(pending))

  @staticmethod
  def size(queue, builder):
    """
        Collect size information about the given queue and builder

        @param queue: The queue for the stage
        @type queue: C{WorkerQueue}
        @param builder: The builder for the stage
        @type builder: C{StageBuilder}
        @return: The size statistics (active, queue, total, workers)
        @rtype: C{(int, int, int, int)}
    """
    return (len(queue), queue.qsize(), len(builder), queue.pool())
<|endoftext|>


<commit_before>import os
import re
import csv
import glob
import time
from temperature_sensor_class import *

def deblank(string:str):
    return string.lstrip().rstrip()

celsius= u'\N{DEGREE SIGN}' + 'C'

#sensor_base_address = '28-000007'
sensor_base_address = ''
sensorID_pattern = '[0-9A-Fa-f]{6}'
regexp = re.compile(sensorID_pattern)

sensor_list = list()
program_list = list()
cellID_list = list()
temperature_list = list()

with open('mapping.csv') as csvfile:
    reader = csv.reader(csvfile, delimiter=',')
    for row in reader:
        if len(row) is 4:
            if regexp.search(row[0]) is not None:
                sensor_list.append(sensor_base_address + deblank(row[0]))
                program_list.append(deblank(row[1]))
                cellID_list.append(deblank(row[2]))
                temperature_list.append(int(row[3]))

print('Found {} valid rows in mapping.CSV'.format(len(sensor_list)))

program_dict = dict(zip(sensor_list, program_list))
cellID_dict = dict(zip(sensor_list, cellID_list))
temperature_dict = dict(zip(sensor_list, temperature_list))

# Turn ON GPIO and temperature sensors
os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')

base_dir = '/sys/bus/w1/devices/'
registered_devices = set()
cells = list()

while True:
    device_folder = glob.glob(base_dir + '28*')

    attached_devices = set()
    detached_devices = set(sensor_list)
    lost_devices = set()

    for device in device_folder:
        sensor_ID = device[-6:]
        if sensor_ID not in attached_devices:
            attached_devices.add(sensor_ID)
            detached_devices.discard(sensor_ID)
            print('Sensor ID {} attached @ {}'.format(sensor_ID, time.ctime()))

    lost_devices = registered_devices.difference(attached_devices)
    for sensor_ID in lost_devices:
        registered_devices.discard(sensor_ID)
        cells[:] = [cell for cell in cells if cell.sensorID is not sensor_ID]
        print('Sensor ID {} lost @ {}'.format(sensor_ID, time.ctime()))

    for sensor_ID in attached_devices:
        if sensor_ID not in registered_devices:
            registered_devices.add(sensor_ID)
            print('Sensor ID {} registered @ {}'.format(sensor_ID, time.ctime()))
            cells.append(MonitoredCell(cellID_dict[sensor_ID], base_dir, sensor_ID, program_dict[sensor_ID], 'NCRB', '001', temperature_dict[sensor_ID], 27, 29, False))

    print(attached_devices)
    print('::::::::::::::')
    print(detached_devices)
    print('::::::::::::::')
    print(registered_devices)
    print('::::::::::::::')
    print(lost_devices)

    print('\nDetected the following {} sensors:\n'.format(len(cells)))
    for cell in cells:
        try:
            cell.update_Temperature()
            cell.check_Status()
            print(str.join(' :: ', (cell.cellID, cell.sensorID[-6:], cell.status, str(cell.currentTemperature) + celsius)))
            # print('Sensor ID: '+ cell.sensorID)
            # print('Cell ID: ' + cell.cellID)
            # print('Ambient temperature: ' + str(cell.ambientTemperature) + celsius)
            # print('Warning: ' + str(cell.warningThreshold) + celsius)
            # print('Alarm: ' + str(cell.alarmThreshold) + celsius)
            # print('These settings are valid') if cell.validSettings else print('These settings are incorrect')
            # print('Current temperature: ' + str(cell.currentTemperature) + celsius)
            # print('Average temperature: ' + str(cell.averageTemperature) + celsius)
            # print('Status: ' + cell.status)
            # print('\n')
        except NameError:
            print('Could not read from device ' + cell.sensorID + '\n')
        except FileNotFoundError:
            print('Could not locate file for device ' + cell.sensorID + '\n')
    time.sleep(60*10)

<commit_msg>update period 60s<commit_after>import os
import re
import csv
import glob
import time
from temperature_sensor_class import *

def deblank(string:str):
    return string.lstrip().rstrip()

celsius= u'\N{DEGREE SIGN}' + 'C'

#sensor_base_address = '28-000007'
sensor_base_address = ''
sensorID_pattern = '[0-9A-Fa-f]{6}'
regexp = re.compile(sensorID_pattern)

sensor_list = list()
program_list = list()
cellID_list = list()
temperature_list = list()

with open('mapping.csv') as csvfile:
    reader = csv.reader(csvfile, delimiter=',')
    for row in reader:
        if len(row) is 4:
            if regexp.search(row[0]) is not None:
                sensor_list.append(sensor_base_address + deblank(row[0]))
                program_list.append(deblank(row[1]))
                cellID_list.append(deblank(row[2]))
                temperature_list.append(int(row[3]))

print('Found {} valid rows in mapping.CSV'.format(len(sensor_list)))

program_dict = dict(zip(sensor_list, program_list))
cellID_dict = dict(zip(sensor_list, cellID_list))
temperature_dict = dict(zip(sensor_list, temperature_list))

# Turn ON GPIO and temperature sensors
os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')

base_dir = '/sys/bus/w1/devices/'
registered_devices = set()
cells = list()

while True:
    device_folder = glob.glob(base_dir + '28*')

    attached_devices = set()
    detached_devices = set(sensor_list)
    lost_devices = set()

    for device in device_folder:
        sensor_ID = device[-6:]
        if sensor_ID not in attached_devices:
            attached_devices.add(sensor_ID)
            detached_devices.discard(sensor_ID)
            print('Sensor ID {} attached @ {}'.format(sensor_ID, time.ctime()))

    lost_devices = registered_devices.difference(attached_devices)
    for sensor_ID in lost_devices:
        registered_devices.discard(sensor_ID)
        cells[:] = [cell for cell in cells if cell.sensorID is not sensor_ID]
        print('Sensor ID {} lost @ {}'.format(sensor_ID, time.ctime()))

    for sensor_ID in attached_devices:
        if sensor_ID not in registered_devices:
            registered_devices.add(sensor_ID)
            print('Sensor ID {} registered @ {}'.format(sensor_ID, time.ctime()))
            cells.append(MonitoredCell(cellID_dict[sensor_ID], base_dir, sensor_ID, program_dict[sensor_ID], 'NCRB', '001', temperature_dict[sensor_ID], 27, 29, False))

    print(attached_devices)
    print('::::::::::::::')
    print(detached_devices)
    print('::::::::::::::')
    print(registered_devices)
    print('::::::::::::::')
    print(lost_devices)

    print('\nDetected the following {} sensors:\n'.format(len(cells)))
    for cell in cells:
        try:
            cell.update_Temperature()
            cell.check_Status()
            print(str.join(' :: ', (cell.cellID, cell.sensorID[-6:], cell.status, str(cell.currentTemperature) + celsius)))
            # print('Sensor ID: '+ cell.sensorID)
            # print('Cell ID: ' + cell.cellID)
            # print('Ambient temperature: ' + str(cell.ambientTemperature) + celsius)
            # print('Warning: ' + str(cell.warningThreshold) + celsius)
            # print('Alarm: ' + str(cell.alarmThreshold) + celsius)
            # print('These settings are valid') if cell.validSettings else print('These settings are incorrect')
            # print('Current temperature: ' + str(cell.currentTemperature) + celsius)
            # print('Average temperature: ' + str(cell.averageTemperature) + celsius)
            # print('Status: ' + cell.status)
            # print('\n')
        except NameError:
            print('Could not read from device ' + cell.sensorID + '\n')
        except FileNotFoundError:
            print('Could not locate file for device ' + cell.sensorID + '\n')
    # Update after a fixed period (in seconds)
    time.sleep(60)

<|endoftext|>


<commit_before>#!/usr/bin/env python
import curses, time, math

import global_mod as g
import footer
from decimal import Decimal

def draw_window(state, old_window):
    # TODO: only draw parts that actually changed
    old_window.clear()
    old_window.refresh()
    window = curses.newwin(19, 76, 0, 0)

    if 'version' in state:
        if state['testnet'] == 1:
            color = curses.color_pair(2)
            window.addstr(1, 1, state['version'] + " (testnet)", color + curses.A_BOLD)
            unit = 'TNC'
        else:
            color = curses.color_pair(1)
            window.addstr(1, 1, state['version'], color + curses.A_BOLD)
            unit = 'BTC'

        if "dev" in g.version:
            color = curses.color_pair(5) + curses.A_REVERSE

        window.addstr(0, 1, "bitcoind-ncurses " + g.version, color + curses.A_BOLD)

    if 'peers' in state:
        if state['peers'] > 0:
            color = 0
        else:
            color = curses.color_pair(3)
        window.addstr(0, 32, str(state['peers']) + " peers    ", color + curses.A_BOLD)

    if 'balance' in state:
        balance_string = "%0.8f" % state['balance'] + " " + unit
        if 'unconfirmedbalance' in state:
            if state['unconfirmedbalance'] != 0:
                balance_string += " (+" + "%0.8f" % state['unconfirmedbalance'] + " unconf)"
        window.addstr(1, 32, balance_string, curses.A_BOLD)

    if 'mininginfo' in state:
        height = str(state['mininginfo']['blocks'])
        if height in state['blocks']:
            blockdata = state['blocks'][str(height)]

            if 'new' in blockdata:
                window.attrset(curses.A_REVERSE + curses.color_pair(5) + curses.A_BOLD)
                blockdata.pop('new')

            window.addstr(3, 1, height.zfill(6) + ": " + str(blockdata['hash']))
            window.addstr(4, 1, str(blockdata['size']) + " bytes (" + str(blockdata['size']/1024) + " KB)       ")
            tx_count = len(blockdata['tx'])
            bytes_per_tx = blockdata['size'] / tx_count
            window.addstr(5, 1, "Transactions: " + str(tx_count) + " (" + str(bytes_per_tx) + " bytes/tx)")

            if 'coinbase_amount' in blockdata:
                halvings = state['mininginfo']['blocks'] / 210000
                block_subsidy = Decimal(50 * (0.5 ** halvings))

                if block_subsidy:
                    coinbase_amount = blockdata['coinbase_amount']
                    total_fees = coinbase_amount - block_subsidy # assumption, mostly correct

                    if coinbase_amount > 0:
                        fee_percentage = "%0.2f" % ((total_fees / coinbase_amount) * 100)
                        coinbase_amount_str = "%0.8f" % coinbase_amount
                        window.addstr(7, 1, "Total block reward: " + coinbase_amount_str + " " + unit + " (" + fee_percentage + "% fees)")

                    if tx_count > 1:
                        tx_count -= 1 # the coinbase can't pay a fee
                        fees_per_tx = (total_fees / tx_count) * 1000
                        fees_per_kb = ((total_fees * 1024) / blockdata['size']) * 1000
                        total_fees_str = "%0.8f" % total_fees + " " + unit
                        fees_per_tx = "%0.5f" % fees_per_tx + " m" + unit + "/tx"
                        fees_per_kb = "%0.5f" % fees_per_kb + " m" + unit + "/KB"
                        window.addstr(8, 1, "Fees: " + total_fees_str + " (avg " +  fees_per_tx + ", ~" + fees_per_kb + ")")

            window.addstr(4, 37, "Block timestamp: " + time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(blockdata['time'])))

            if state['lastblocktime'] == 0:
                recvdelta_string = "        "
            else:
                recvdelta = int(time.time() - state['lastblocktime'])
                m, s = divmod(recvdelta, 60)
                h, m = divmod(m, 60)
                recvdelta_string = "{:02d}:{:02d}:{:02d}".format(h,m,s)

            stampdelta = int(time.time() - blockdata['time'])
            if stampdelta > 3600*3: # probably syncing if it's three hours old
                stampdelta_string = "             (syncing)"
            elif stampdelta > 0:
                m, s = divmod(stampdelta, 60)
                h, m = divmod(m, 60)
                d, h = divmod(h, 24)
                stampdelta_string = "({:d}d {:02d}:{:02d}:{:02d} by stamp)".format(d,h,m,s)
            else:
                stampdelta_string = "     (stamp in future)"

            window.addstr(5, 37, "Age: " + recvdelta_string + " " + stampdelta_string)

            if 'chainwork' in blockdata:
                log2_chainwork = math.log(int(blockdata['chainwork'], 16), 2)
                window.addstr(14, 1, "Chain work: 2**" + "%0.6f" % log2_chainwork)

        diff = int(state['mininginfo']['difficulty'])
        window.addstr(10, 1, "Diff:        " + "{:,d}".format(diff))

    for block_avg in state['networkhashps']:
        index = 10

        if block_avg == 'diff':
            pass
        elif block_avg == 2016:
            index += 1
        elif block_avg == 144:
            index += 2
        else:
            break

        rate = state['networkhashps'][block_avg]
        if block_avg != 'diff':
            nextdiff = (rate*600)/(2**32)
            if state['testnet'] == 1:
                nextdiff *= 2 # testnet has 1200 est. block interval, not 600
            window.addstr(index, 1, "Est (" + str(block_avg).rjust(4) + "): ~" + "{:,}".format(nextdiff))

        if rate > 10**18:
            rate /= 10**18
            suffix = " EH/s"
        elif rate > 10**12:
            rate /= 10**12
            suffix = " TH/s"
        else:
            rate /= 10**6
            suffix = " MH/s"
        rate_string = "{:,}".format(rate) + suffix
        window.addstr(index, 37, "Hashrate (" + str(block_avg).rjust(4) + "): " + rate_string.rjust(13))
        index += 1

        pooledtx = state['mininginfo']['pooledtx']
        window.addstr(14, 37, "Mempool transactions: " + "% 5d" % pooledtx)

    if 'totalbytesrecv' in state:
        recvmb = "%.2f" % (state['totalbytesrecv']*1.0/1048576)
        sentmb = "%.2f" % (state['totalbytessent']*1.0/1048576)
        recvsent_string = "D/U: " + recvmb + " / " + sentmb + " MB"
        window.addstr(0, 43, recvsent_string.rjust(30), curses.A_BOLD)

    if 'estimatefee' in state:
        string = "estimatefee:"
        for blocks in state['estimatefee']:
            est = state['estimatefee'][blocks]
            if est > 0:
                string += " (" + str(blocks) + ")" + "%4.2f" % (est*1000) + "m" + unit
        if len(string) > 12:
            window.addstr(15, 37, string)

    if 'mininginfo' in state:
        # errors = state['mininginfo']['errors']
        # TODO: Remove this for production.
        errors = "This is a development version of bitcoind-ncurses. Expect breakage."
        if len(errors):
            if state['y'] < 20:
                y = state['y'] - 3
            else:
                y = 17
            window.addstr(y, 1, errors[:72].ljust(72), curses.color_pair(5) + curses.A_BOLD + curses.A_REVERSE)
            window.addstr(y+1, 1, errors[72:142].rjust(72), curses.color_pair(5) + curses.A_BOLD + curses.A_REVERSE)

    window.refresh()
    footer.draw_window(state)
<commit_msg>Fix incorrect formatting for hashrate based on diff<commit_after>#!/usr/bin/env python
import curses, time, math

import global_mod as g
import footer
from decimal import Decimal

def draw_window(state, old_window):
    # TODO: only draw parts that actually changed
    old_window.clear()
    old_window.refresh()
    window = curses.newwin(19, 76, 0, 0)

    if 'version' in state:
        if state['testnet'] == 1:
            color = curses.color_pair(2)
            window.addstr(1, 1, state['version'] + " (testnet)", color + curses.A_BOLD)
            unit = 'TNC'
        else:
            color = curses.color_pair(1)
            window.addstr(1, 1, state['version'], color + curses.A_BOLD)
            unit = 'BTC'

        if "dev" in g.version:
            color = curses.color_pair(5) + curses.A_REVERSE

        window.addstr(0, 1, "bitcoind-ncurses " + g.version, color + curses.A_BOLD)

    if 'peers' in state:
        if state['peers'] > 0:
            color = 0
        else:
            color = curses.color_pair(3)
        window.addstr(0, 32, str(state['peers']) + " peers    ", color + curses.A_BOLD)

    if 'balance' in state:
        balance_string = "%0.8f" % state['balance'] + " " + unit
        if 'unconfirmedbalance' in state:
            if state['unconfirmedbalance'] != 0:
                balance_string += " (+" + "%0.8f" % state['unconfirmedbalance'] + " unconf)"
        window.addstr(1, 32, balance_string, curses.A_BOLD)

    if 'mininginfo' in state:
        height = str(state['mininginfo']['blocks'])
        if height in state['blocks']:
            blockdata = state['blocks'][str(height)]

            if 'new' in blockdata:
                window.attrset(curses.A_REVERSE + curses.color_pair(5) + curses.A_BOLD)
                blockdata.pop('new')

            window.addstr(3, 1, height.zfill(6) + ": " + str(blockdata['hash']))
            window.addstr(4, 1, str(blockdata['size']) + " bytes (" + str(blockdata['size']/1024) + " KB)       ")
            tx_count = len(blockdata['tx'])
            bytes_per_tx = blockdata['size'] / tx_count
            window.addstr(5, 1, "Transactions: " + str(tx_count) + " (" + str(bytes_per_tx) + " bytes/tx)")

            if 'coinbase_amount' in blockdata:
                halvings = state['mininginfo']['blocks'] / 210000
                block_subsidy = Decimal(50 * (0.5 ** halvings))

                if block_subsidy:
                    coinbase_amount = blockdata['coinbase_amount']
                    total_fees = coinbase_amount - block_subsidy # assumption, mostly correct

                    if coinbase_amount > 0:
                        fee_percentage = "%0.2f" % ((total_fees / coinbase_amount) * 100)
                        coinbase_amount_str = "%0.8f" % coinbase_amount
                        window.addstr(7, 1, "Total block reward: " + coinbase_amount_str + " " + unit + " (" + fee_percentage + "% fees)")

                    if tx_count > 1:
                        tx_count -= 1 # the coinbase can't pay a fee
                        fees_per_tx = (total_fees / tx_count) * 1000
                        fees_per_kb = ((total_fees * 1024) / blockdata['size']) * 1000
                        total_fees_str = "%0.8f" % total_fees + " " + unit
                        fees_per_tx = "%0.5f" % fees_per_tx + " m" + unit + "/tx"
                        fees_per_kb = "%0.5f" % fees_per_kb + " m" + unit + "/KB"
                        window.addstr(8, 1, "Fees: " + total_fees_str + " (avg " +  fees_per_tx + ", ~" + fees_per_kb + ")")

            window.addstr(4, 37, "Block timestamp: " + time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(blockdata['time'])))

            if state['lastblocktime'] == 0:
                recvdelta_string = "        "
            else:
                recvdelta = int(time.time() - state['lastblocktime'])
                m, s = divmod(recvdelta, 60)
                h, m = divmod(m, 60)
                recvdelta_string = "{:02d}:{:02d}:{:02d}".format(h,m,s)

            stampdelta = int(time.time() - blockdata['time'])
            if stampdelta > 3600*3: # probably syncing if it's three hours old
                stampdelta_string = "             (syncing)"
            elif stampdelta > 0:
                m, s = divmod(stampdelta, 60)
                h, m = divmod(m, 60)
                d, h = divmod(h, 24)
                stampdelta_string = "({:d}d {:02d}:{:02d}:{:02d} by stamp)".format(d,h,m,s)
            else:
                stampdelta_string = "     (stamp in future)"

            window.addstr(5, 37, "Age: " + recvdelta_string + " " + stampdelta_string)

            if 'chainwork' in blockdata:
                log2_chainwork = math.log(int(blockdata['chainwork'], 16), 2)
                window.addstr(14, 1, "Chain work: 2**" + "%0.6f" % log2_chainwork)

        diff = int(state['mininginfo']['difficulty'])
        window.addstr(10, 1, "Diff:        " + "{:,d}".format(diff))

    for block_avg in state['networkhashps']:
        index = 10

        if block_avg == 'diff':
            pass
        elif block_avg == 2016:
            index += 1
        elif block_avg == 144:
            index += 2
        else:
            break

        rate = state['networkhashps'][block_avg]
        if block_avg != 'diff':
            nextdiff = (rate*600)/(2**32)
            if state['testnet'] == 1:
                nextdiff *= 2 # testnet has 1200 est. block interval, not 600
            window.addstr(index, 1, "Est (" + str(block_avg).rjust(4) + "): ~" + "{:,}".format(nextdiff))

        if rate > 10**18:
            rate = float(rate)/10**18
            suffix = " EH/s"
        elif rate > 10**12:
            rate = float(rate)/10**12
            suffix = " TH/s"
        else:
            rate = float(rate)/10**6
            suffix = " MH/s"
        rate_string = "{:,}".format(rate) + suffix
        window.addstr(index, 37, "Hashrate (" + str(block_avg).rjust(4) + "): " + rate_string.rjust(13))
        index += 1

        pooledtx = state['mininginfo']['pooledtx']
        window.addstr(14, 37, "Mempool transactions: " + "% 5d" % pooledtx)

    if 'totalbytesrecv' in state:
        recvmb = "%.2f" % (state['totalbytesrecv']*1.0/1048576)
        sentmb = "%.2f" % (state['totalbytessent']*1.0/1048576)
        recvsent_string = "D/U: " + recvmb + " / " + sentmb + " MB"
        window.addstr(0, 43, recvsent_string.rjust(30), curses.A_BOLD)

    if 'estimatefee' in state:
        string = "estimatefee:"
        for blocks in state['estimatefee']:
            est = state['estimatefee'][blocks]
            if est > 0:
                string += " (" + str(blocks) + ")" + "%4.2f" % (est*1000) + "m" + unit
        if len(string) > 12:
            window.addstr(15, 37, string)

    if 'mininginfo' in state:
        # errors = state['mininginfo']['errors']
        # TODO: Remove this for production.
        errors = "This is a development version of bitcoind-ncurses. Expect breakage."
        if len(errors):
            if state['y'] < 20:
                y = state['y'] - 3
            else:
                y = 17
            window.addstr(y, 1, errors[:72].ljust(72), curses.color_pair(5) + curses.A_BOLD + curses.A_REVERSE)
            window.addstr(y+1, 1, errors[72:142].rjust(72), curses.color_pair(5) + curses.A_BOLD + curses.A_REVERSE)

    window.refresh()
    footer.draw_window(state)
<|endoftext|>


<commit_before>##
# The MIT License (MIT)
#
# Copyright (c) 2016 Stefan Wendler
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
##

import serial

if serial.VERSION.startswith("2."):

    # see if we could use the legacy Miniterm implementation
    from serial.tools.miniterm import (
        Miniterm,
        console,
        CONVERT_CRLF,
        CONVERT_CR,
        CONVERT_LF,
        NEWLINE_CONVERISON_MAP,
    )

    class Term(Miniterm):
        def __init__(self, serial_instance, echo=False, eol="crlf"):

            self.serial = serial_instance

            convert = {"cr": CONVERT_CR, "lf": CONVERT_LF, "crlf": CONVERT_CRLF}

            self.console = console
            self.echo = echo
            self.repr_mode = 0
            self.convert_outgoing = convert[eol]
            self.newline = NEWLINE_CONVERISON_MAP[self.convert_outgoing]
            self.dtr_state = True
            self.rts_state = True
            self.break_state = False

            self.exit_character = None
            self.menu_character = None
            self.raw = None

            self.console.setup()

        def set_rx_encoding(self, enc):
            pass

        def set_tx_encoding(self, enc):
            pass

else:

    # see if we could use the new Miniterm implementation
    from serial.tools.miniterm import Miniterm

    Term = Miniterm
<commit_msg>fix: fix win10 console out garbled code when used up/down/left/right/tab.... (#67)<commit_after>##
# The MIT License (MIT)
#
# Copyright (c) 2016 Stefan Wendler
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
##

import serial

if serial.VERSION.startswith("2."):

    # see if we could use the legacy Miniterm implementation
    from serial.tools.miniterm import (
        Miniterm,
        console,
        CONVERT_CRLF,
        CONVERT_CR,
        CONVERT_LF,
        NEWLINE_CONVERISON_MAP,
    )

    class Term(Miniterm):
        def __init__(self, serial_instance, echo=False, eol="crlf"):

            self.serial = serial_instance

            convert = {
                "cr": CONVERT_CR,
                "lf": CONVERT_LF,
                "crlf": CONVERT_CRLF
            }

            self.console = console
            self.echo = echo
            self.repr_mode = 0
            self.convert_outgoing = convert[eol]
            self.newline = NEWLINE_CONVERISON_MAP[self.convert_outgoing]
            self.dtr_state = True
            self.rts_state = True
            self.break_state = False

            self.exit_character = None
            self.menu_character = None
            self.raw = None

            self.console.setup()

        def set_rx_encoding(self, enc):
            pass

        def set_tx_encoding(self, enc):
            pass

else:

    # see if we could use the new Miniterm implementation
    from serial.tools.miniterm import Miniterm, ConsoleBase, unichr
    import os
    if os.name == 'nt':  # noqa
        import codecs
        import sys
        import msvcrt
        import ctypes
        import platform

        class Out(object):
            """file-like wrapper that uses os.write"""

            def __init__(self, fd):
                self.fd = fd

            def flush(self):
                pass

            def write(self, s):
                os.write(self.fd, s)

        class Console(ConsoleBase):
            fncodes = {
                ';': '\1bOP',  # F1
                '<': '\1bOQ',  # F2
                '=': '\1bOR',  # F3
                '>': '\1bOS',  # F4
                '?': '\1b[15~',  # F5
                '@': '\1b[17~',  # F6
                'A': '\1b[18~',  # F7
                'B': '\1b[19~',  # F8
                'C': '\1b[20~',  # F9
                'D': '\1b[21~',  # F10
            }
            navcodes = {
                'H': '\x1b[A',  # UP
                'P': '\x1b[B',  # DOWN
                'K': '\x1b[D',  # LEFT
                'M': '\x1b[C',  # RIGHT
                'G': '\x1b[H',  # HOME
                'O': '\x1b[F',  # END
                'R': '\x1b[2~',  # INSERT
                'S': '\x1b[3~',  # DELETE
                'I': '\x1b[5~',  # PGUP
                'Q': '\x1b[6~',  # PGDN
            }

            def __init__(self):
                super(Console, self).__init__()
                self._saved_ocp = ctypes.windll.kernel32.GetConsoleOutputCP()
                self._saved_icp = ctypes.windll.kernel32.GetConsoleCP()
                ctypes.windll.kernel32.SetConsoleOutputCP(65001)
                ctypes.windll.kernel32.SetConsoleCP(65001)
                # ANSI handling available through SetConsoleMode since Windows 10 v1511
                # https://en.wikipedia.org/wiki/ANSI_escape_code#cite_note-win10th2-1
                # if platform.release() == '10' and int(platform.version().split('.')[2]) > 10586:
                ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004
                import ctypes.wintypes as wintypes
                if not hasattr(wintypes, 'LPDWORD'): # PY2
                    wintypes.LPDWORD = ctypes.POINTER(wintypes.DWORD)
                SetConsoleMode = ctypes.windll.kernel32.SetConsoleMode
                GetConsoleMode = ctypes.windll.kernel32.GetConsoleMode
                GetStdHandle = ctypes.windll.kernel32.GetStdHandle
                mode = wintypes.DWORD()
                GetConsoleMode(GetStdHandle(-11), ctypes.byref(mode))
                if (mode.value & ENABLE_VIRTUAL_TERMINAL_PROCESSING) == 0:
                    SetConsoleMode(GetStdHandle(-11), mode.value | ENABLE_VIRTUAL_TERMINAL_PROCESSING)
                    self._saved_cm = mode
                self.output = codecs.getwriter('UTF-8')(Out(sys.stdout.fileno()), 'replace')
                # the change of the code page is not propagated to Python, manually fix it
                sys.stderr = codecs.getwriter('UTF-8')(Out(sys.stderr.fileno()), 'replace')
                sys.stdout = self.output
                self.output.encoding = 'UTF-8'  # needed for input

            def __del__(self):
                ctypes.windll.kernel32.SetConsoleOutputCP(self._saved_ocp)
                ctypes.windll.kernel32.SetConsoleCP(self._saved_icp)
                try:
                    ctypes.windll.kernel32.SetConsoleMode(ctypes.windll.kernel32.GetStdHandle(-11), self._saved_cm)
                except AttributeError: # in case no _saved_cm
                    pass

            def getkey(self):
                while True:
                    z = msvcrt.getwch()
                    if z == unichr(13):
                        return unichr(10)
                    elif z is unichr(0) or z is unichr(0xe0):
                        try:
                            code = msvcrt.getwch()
                            if z is unichr(0):
                                return self.fncodes[code]
                            else:
                                return self.navcodes[code]
                        except KeyError:
                            pass
                    else:
                        return z

            def cancel(self):
                # CancelIo, CancelSynchronousIo do not seem to work when using
                # getwch, so instead, send a key to the window with the console
                hwnd = ctypes.windll.kernel32.GetConsoleWindow()
                ctypes.windll.user32.PostMessageA(hwnd, 0x100, 0x0d, 0)

        class Term(Miniterm):

            def __init__(self, serial_instance, echo=False, eol='crlf', filters=()):
                self.console = Console()
                self.serial = serial_instance
                self.echo = echo
                self.raw = False
                self.input_encoding = 'UTF-8'
                self.output_encoding = 'UTF-8'
                self.eol = eol
                self.filters = filters
                self.update_transformations()
                self.exit_character = unichr(0x1d)  # GS/CTRL+]
                self.menu_character = unichr(0x14)  # Menu: CTRL+T
                self.alive = None
                self._reader_alive = None
                self.receiver_thread = None
                self.rx_decoder = None
                self.tx_decoder = None
    else:
        Term = Miniterm
<|endoftext|>


<commit_before>from __future__ import division

from nose.tools import *

import numpy as np

from dit.algorithms import entropy
from dit.example_dists import bernoulli, binomial, uniform

def test_bernoulli1():
    d = bernoulli(1/2)
    assert_equal(d.outcomes, (0,1))
    assert_almost_equal(sum(d.pmf), 1)

def test_bernoulli2():
    for p in [ i/10 for i in range(0, 11)]:
        d = bernoulli(p)
        assert_almost_equal(d[0], 1-p)
        assert_almost_equal(d[1], p)

def test_bernoulli3():
    for p in [-1, 1.5, 'a', int, []]:
        assert_raises(ValueError, bernoulli, p)

def test_binomial1():
    for n in range(1, 10):
        d = binomial(n, 1/2)
        assert_equal(d.outcomes, tuple(range(n+1)))
        assert_almost_equal(sum(d.pmf), 1)

def test_binomial2():
    for n in [-1, 1.5, 'a', int, []]:
        assert_raises(ValueError, binomial, n, 1/2)

def test_uniform1():
    for n in range(2, 10):
        d = uniform(n)
        assert_almost_equal(d.outcomes, tuple(range(n)))
        assert_almost_equal(d[0], 1/n)
        assert_almost_equal(entropy(d), np.log2(n))<commit_msg>tweak a test for py2.6 compatibility<commit_after>from __future__ import division

from nose.tools import *

import numpy as np

from dit.algorithms import entropy
from dit.example_dists import bernoulli, binomial, uniform

def test_bernoulli1():
    d = bernoulli(1/2)
    assert_equal(d.outcomes, (0,1))
    assert_almost_equal(sum(d.pmf), 1)

def test_bernoulli2():
    for p in [ i/10 for i in range(0, 11)]:
        d = bernoulli(p)
        assert_almost_equal(d[0], 1-p)
        assert_almost_equal(d[1], p)

def test_bernoulli3():
    for p in [-1, 1.5, 'a', int, []]:
        assert_raises(ValueError, bernoulli, p)

def test_binomial1():
    for n in range(1, 10):
        d = binomial(n, 1/2)
        assert_equal(d.outcomes, tuple(range(n+1)))
        assert_almost_equal(sum(d.pmf), 1)

def test_binomial2():
    for n in [-1, 1.5, 'a', int, []]:
        assert_raises(ValueError, binomial, n, 1/2)

def test_uniform1():
    for n in range(2, 10):
        d = uniform(n)
        assert_equal(d.outcomes, tuple(range(n)))
        assert_almost_equal(d[0], 1/n)
        assert_almost_equal(entropy(d), np.log2(n))<|endoftext|>