def handle_read(self, dgram_spec=AVR_Datagram.AVR_PC_Status): """Attempt to read a datagram from the serial port. Look for a bytes matching AVR_Datagram.expect_dgram_start(), and read additional bytes until we have a byte sequence of total length == AVR_Datagram.full_dgram_len(). """ d_start = AVR_Datagram.expect_dgram_start(dgram_spec) assert isinstance(d_start, bytes) d_len = AVR_Datagram.full_dgram_len(dgram_spec) assert len(d_start) < d_len assert len(self.readbuf) < d_len # self.debug("Have %u bytes" % (len(self.readbuf))) self.readbuf += self.ser.read(d_len - len(self.readbuf)) if len(self.readbuf) < d_len: # self.debug("Incomplete dgram (got %u/%u bytes): %s" % ( # len(self.readbuf), d_len, # self.human_readable(self.readbuf))) return # Find start of datagram i = self.readbuf.find(d_start) if i < 0: # beyond len(self.readbuf) - len(d_start) # self.debug("No start of dgram in %u bytes: %s" % ( # len(self.readbuf), # self.human_readable(self.readbuf))) self.readbuf = self.readbuf[-(len(d_start) - 1):] return elif i > 0: # dgram starts at index i # self.debug("dgram starts at index %u in %s" % (i, # self.human_readable(self.readbuf))) self.readbuf = self.readbuf[i:] assert self.readbuf.startswith(d_start) if len(self.readbuf) < d_len: return # self.debug("parsing self.readbuf: %s" % ( # self.human_readable(self.readbuf))) dgram, self.readbuf = self.readbuf[:d_len], self.readbuf[d_len:] assert isinstance(dgram, bytes) data = AVR_Datagram.parse_dgram(dgram, dgram_spec) status = AVR_Status.from_dgram(data) if self.state.update(status): self.debug("%s\n\t\t-> %s" % (status, self.state)) if self.status_handler: self.status_handler(status) self.ready_to_write(True)
def handle_read(self): self.recv_data += os.read(self.master, 1024) while len(self.recv_data) >= self.recv_dgram_len: dgram = self.recv_data[:self.recv_dgram_len] self.recv_data = self.recv_data[self.recv_dgram_len:] self.handle_command(AVR_Command.from_dgram( AVR_Datagram.parse_dgram(dgram, self.RecvDGramSpec)))
def handle_cmd(self, cmd, rest): if self.state.off: self.debug("Discarding '%s' while AVR is off" % (cmd)) return self.debug("Handling '%s'" % (cmd)) avr, cmd = cmd.split(" ", 1) assert avr == self.name assert cmd in self.Commands assert not rest command = self.Commands[cmd] assert callable(command) for command_str in command(self): avr_cmd = AVR_Command(command_str) dgram_spec = AVR_Datagram.PC_AVR_Command dgram = AVR_Datagram.build_dgram(avr_cmd.dgram(), dgram_spec) self.schedule_write(dgram)
def __init__(self, av_loop, name): Fake_SerialDevice.__init__(self, av_loop, name) self.standby = True self.mute = False self.volume = -35 # dB self.status_queue = TimedQueue(self.gen_status("standby")) self.write_timer = PeriodicCallback(self.write_now, 50, av_loop) self.write_timer.start() self.recv_dgram_len = AVR_Datagram.full_dgram_len(self.RecvDGramSpec) self.recv_data = "" # Receive buffer self.t0 = time.time()
def write_now(self): os.write(self.master, AVR_Datagram.build_dgram( self.status().dgram(), self.SendDGramSpec))