示例#1
0
 def __init__(self, stream=None):
     log.info("stream=%s", stream)
     if not stream:
         stream = BytesIO()
     self.readpos = 0
     self.writepos = 0
     super().__init__(stream)
示例#2
0
 def read(self, bytelen=0, *args, **kwargs):
     log.info("bytelen=%s args=%s kwargs=%s", bytelen, args, kwargs)
     if not bytelen:
         waiting = self.stream.inWaiting()
         inbuffer = len(self.buffer)
         waitfor = waiting + inbuffer
         log.info(
             "serial stream bytelen=%s waiting=%s inbuffer=%d setting to %s",
             bytelen, waiting, inbuffer, waitfor)
         bytelen = waitfor
     return super().read(bytelen, *args, **kwargs)
示例#3
0
 def write(self, buf, *args, **kwargs):
     log.info("buf=%s args=%s kwargs=%s", buf, args, kwargs)
     log.info("writepos=%s", self.writepos)
     self.stream.seek(self.writepos)
     result = super().write(bytes(buf), *args, **kwargs)
     self.writepos += result
     log.info("return result=%s", result)
     return result
示例#4
0
 def cleanup():
     log.warning("Cleanup: killing socat process")
     socat.kill()
     if cleanup_hardware:
         try:
             log.warning("Cleanup: removing hardware file %s" %
                         (hardware))
             os.remove(hardware)
         except:
             pass  # possibly a race condition with socat dying and not removing this quickly enough
     if cleanup_software:
         try:
             log.warning("Cleanup: removing software file %s" %
                         (software))
             os.remove(software)
         except:
             pass  # possibly a race condition with socat dying and not removing this quickly enough
     if cleanup_tempdir:
         if os.path.isdir(tempdir):
             log.warning("Cleanup: removing temp directory %s" %
                         (tempdir))
             os.rmdir(tempdir)
     log.warning("Cleanup: done")
示例#5
0
 def read(self, bytelen=0, *args, **kwargs):
     log.info("bytelen=%s args=%s kwargs=%s", bytelen, args, kwargs)
     log.info("readpos=%s", self.readpos)
     self.stream.seek(self.readpos)
     pre = self.stream.tell()
     buf = super().read(bytelen=bytelen, *args, **kwargs)
     post = self.stream.tell()
     self.readpos += post - pre
     log.info("return buf=%s", buf)
     return buf
示例#6
0
 def read(self, bytelen=0, *args, **kwargs):
     log.info("bytelen=%s args=%s kwargs=%s", bytelen, args, kwargs)
     if bytelen:
         if bytelen > len(self.buffer):
             self.buffer += self.stream.read(bytelen - len(self.buffer),
                                             *args, **kwargs)
         log.info("return buffer[:%s]=%s", bytelen, self.buffer[:bytelen])
         return self.buffer[:bytelen]
     else:
         self.buffer += self.stream.read(*args, **kwargs)
         log.info("return buffer=%s", self.buffer)
         return self.buffer
示例#7
0
 def receiveReply(self, command_id):
     log.info("command_id=%s", command_id)
     bridge_klass = getBridgeReplyByID(command_id)
     sensor_klass = getSensorReplyByID(command_id)
     if not bridge_klass:
         log.error("Command ID not recognized: %s", command_id)
         return None
     if bridge_klass is BridgeNull:
         log.info("bridge reply is BridgeNull")
         return bridge_klass()
     bridgebuf = self.read(0)
     log.info("bridgebuf=%s", bridgebuf)
     try:
         bridge_reply = bridge_klass(bridgebuf)
     except Exception as e:
         log.info("bridgebuf=%s exception=%s", bridgebuf, str(e))
         return None
     if not hasattr(bridge_reply, "status") or bridge_reply.status is None:
         log.info("bridge reply is empty")
         return None
     bridgelen = len(bytes(bridge_reply))
     self.consume(bridgelen)
     bridgebuf = bridgebuf[0:bridgelen]
     if bridge_reply.status != 0 or not sensor_klass:
         log.info("return bridge_reply=%s", bridge_reply)
         return bridge_reply
     sensorbuf = self.read(0)
     log.info("bridgebuf=%s", sensorbuf)
     try:
         sensor_reply = sensor_klass(sensorbuf)
     except Exception as e:
         log.info("sensorbuf=%s exception=%s pushing back bridgebuf=%s",
                  sensorbuf, str(e), bridgebuf)
         self.pushback(bridgebuf)
         return None
     if sensor_reply.status is None:
         log.info("sensor reply is empty")
         self.pushback(bridgebuf)
         return None
     self.consume(len(bytes(sensor_reply)))
     log.info("return sensor_reply=%s", sensor_reply)
     return sensor_reply
示例#8
0
 def sendReply(self, reply):
     log.info("reply=%s", reply)
     result = self.write(reply)
     log.info("return result=%s", result)
     return result
示例#9
0
 def sendCommand(self, command):
     log.info("command=%s", command)
     return self.write(command)
示例#10
0
 def receiveCommand(self):
     log.info("read 1")
     command_id = self.read(1)
     if len(command_id) < 1:
         log.info("Did not read one byte of command_id")
         return None
     klass = getCommandByID(unpack(b'B', command_id)[0])
     if not klass:
         log.error("Command ID not recognized: %s", command_id)
         return None
     command = klass()
     self.consume(1)
     if len(command) > 1:
         buf = command_id + self.read(len(command) - 1)
     else:
         buf = command_id
     if len(buf) < len(command):
         log.info("Read only %s of %s bytes", len(buf), len(command))
         self.pushback(command_id)
         return None
     try:
         log.info("unpack %s", buf)
         command.unpack(buf)
     except Exception as e:
         log.info("Cannot unpack buf=%s exception=%s", buf, str(e))
         return None
     self.consume(len(command) - 1)
     log.info("return %s", command)
     return command
示例#11
0
 def write(self, buf, *args, **kwargs):
     log.info("buf=%s args=%s kwargs=%s", buf, args, kwargs)
     buf = self.stream.write(bytes(buf), *args, **kwargs)
     log.info("return buf=%s", buf)
     return buf
示例#12
0
 def pushback(self, buf):
     log.info("buf=%s", buf)
     self.buffer = buf + self.buffer
     log.info("return")
示例#13
0
 def consume(self, bytelen):
     log.info("bytelen=%s", bytelen)
     self.buffer = self.buffer[bytelen:]
     log.info("return")
示例#14
0
 def cleanup():
     log.warning("Cleanup: killing emulator process")
     fork.kill()
     log.warning("Cleanup: done")
示例#15
0
    def __init__(self,
                 hardware=None,
                 software=None,
                 timeout=None,
                 socat=False,
                 fork=False,
                 *args,
                 **kwargs):
        log.info("hardware=%s software=%s timeout=%s args=%s kwargs=%s",
                 hardware, software, timeout, args, kwargs)
        cleanup_hardware = False
        cleanup_software = False
        cleanup_tempdir = False

        if not hardware or not software:
            tempdir = tempfile.mkdtemp()
            cleanup_tempdir = True

        if not hardware:
            hardware = os.path.join(tempdir, "chromation.hardware")
            cleanup_hardware = True

        if not software:
            software = os.path.join(tempdir, "chromation.software")
            cleanup_software = True

        if socat:
            log.info("forking socat process")
            #TODO: make this work for PC as well as MAC
            # Note: the -D is there to print something, anything, to stderr, so we can wait for it
            socat = subprocess.Popen([
                "socat", "-D",
                "PTY,raw,echo=0,link=%s" % (hardware),
                "PTY,raw,echo=0,link=%s" % (software)
            ],
                                     stderr=subprocess.PIPE)

            # Wait at most a second for socat to come up and announce itself, by which time the
            # files it needs to create should be there:
            r, w, x = select.select([socat.stderr], [], [], 1)
            #import pdb; pdb.set_trace();
            if not r:
                raise MicroSpecEmulationException(
                    "Cannot create socat process to mediate USB emulation!")

            def cleanup():
                log.warning("Cleanup: killing socat process")
                socat.kill()
                if cleanup_hardware:
                    try:
                        log.warning("Cleanup: removing hardware file %s" %
                                    (hardware))
                        os.remove(hardware)
                    except:
                        pass  # possibly a race condition with socat dying and not removing this quickly enough
                if cleanup_software:
                    try:
                        log.warning("Cleanup: removing software file %s" %
                                    (software))
                        os.remove(software)
                    except:
                        pass  # possibly a race condition with socat dying and not removing this quickly enough
                if cleanup_tempdir:
                    if os.path.isdir(tempdir):
                        log.warning("Cleanup: removing temp directory %s" %
                                    (tempdir))
                        os.rmdir(tempdir)
                log.warning("Cleanup: done")

            atexit.register(cleanup)
            self.socat = socat

        if fork:
            log.info("forking emulator process")
            # -p so that we can capture the stdout to make sure it's up and running
            fork = subprocess.Popen(
                ["microspec_emulator.py", "-t", "10", "-p", "-f", hardware],
                stdout=subprocess.PIPE)

            # Wait at most a second for emulator to come up and announce itself, by which time it
            # should have it's socket open and waiting
            r, w, x = select.select([fork.stdout], [], [], 1)
            #import pdb; pdb.set_trace();
            if not r:
                raise MicroSpecEmulationException(
                    "Cannot create emulator process for USB emulation!")

            def cleanup():
                log.warning("Cleanup: killing emulator process")
                fork.kill()
                log.warning("Cleanup: done")

            atexit.register(cleanup)
            self.fork = fork

        self.hardware = hardware
        self.software = software

        super().__init__(device=hardware, timeout=timeout)
示例#16
0
 def __init__(self,
              serial_number=None,
              device=None,
              timeout=0,
              *args,
              **kwargs):
     log.info("serial_number=%s device=%s timeout=%s args=%s kwargs=%s",
              serial_number, device, timeout, args, kwargs)
     self.serial = Serial(*args, **kwargs)
     self.serial.baudrate = 115200
     self.serial.timeout = timeout
     self.serial.port = None
     if serial_number:
         ports = list(list_ports.grep(serial_number))
         if ports:
             self.serial.port = ports[0].device
             self.serial.serial_number = ports[0].serial_number
             log.info("search for serial_number=%s found port=%s",
                      serial_number, self.serial.port)
     elif device:
         self.serial.port = device
         log.info("using device=%s", device)
     else:
         # NOTE: 2021-06-23 (sustainablelab)
         # Long serial numbers are no longer supported
         # Change "CHROMATION" to "CH"
         # ports = list(list_ports.grep("CHROMATION"))
         ports = list(list_ports.grep("CH"))
         if ports:
             self.serial.port = ports[0].device
             self.serial.serial_number = ports[0].serial_number
             log.info(
                 "defaulting to searching for CHROMATION hardware, "
                 "found port=%s, serial_number=", self.serial.port,
                 self.serial.serial_number)
         if not self.serial.port:
             for port in list_ports.comports(True):
                 if port.vid == 1027 and port.pid == 24597:
                     self.serial.port = port.device
                     break
     if not self.serial.port:
         log.error("Cannot find CHROMATION device")
         raise MicroSpecConnectionException("Cannot find CHROMATION device")
     try:
         self.serial.open()
     except Exception as e:
         log.error(
             "Cannot open device: check if port is already in use, such as another MicroSpec interface is using it: %s"
             % (e))
         raise MicroSpecConnectionException(str(e))
     super().__init__(self.serial)
     log.info("return")
示例#17
0
 def __init__(self, stream):
     log.info("stream=%s", stream)
     self.stream = stream
     self.buffer = b''
     log.info("return")