Beispiel #1
0
    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()
Beispiel #2
0
class Fake_AVR(Fake_SerialDevice):
    """Impersonate an AVR unit.

    Receive remote commands, update internal state and provide plausible
    AVR_Status messages.
    """

    Description = "Fake Harman/Kardon AVR 430"

    EmptyIcons = bytes([0x00] * 14)
    DefaultIcons = bytes(
        [0xc0, 0x00, 0x00, 0x00, 0xfd, 0xfb, 0x7a, 0x00, 0xc0] + [0x00] * 5)

    StatusMap = {
        "standby": ("              ", "              ", EmptyIcons),
        "default": ("FAKE AVR      ", "DOLBY DIGITAL ", DefaultIcons),
        "mute": ("     MUTE     ", "              ", DefaultIcons),
        "volume": ("FAKE AVR      ", "  VOL %(volume)3i dB  ", DefaultIcons),
    }

    RecvDGramSpec = (b"PCSEND", 2, 4)  # Receive PC->AVR remote commands
    SendDGramSpec = (b"MPSEND", 3, 48)  # Send AVR->PC status updates

    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 __del__(self):
        self.write_timer.stop()

    def write_now(self):
        os.write(self.master, AVR_Datagram.build_dgram(
            self.status().dgram(), self.SendDGramSpec))

    def status(self):
        """Return AVR_Status diagram for current state."""
        return self.status_queue.current()

    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 gen_status(self, key):
        line1, line2, icons = self.StatusMap[key]
        d = self.__dict__
        return AVR_Status(line1 % d, line2 % d, icons)

    def handle_command(self, cmd):
        now = time.time()
        print("%7.2f: %10s" % (now - self.t0, cmd.keyword), end=' ')
        if self.standby:
            if cmd.keyword == "POWER ON":
                self.standby = False
                self.status_queue.flush(self.gen_status("default"))
        else:
            if cmd.keyword == "POWER OFF":
                self.standby = True
                self.status_queue.flush(self.gen_status("standby"))
            elif cmd.keyword == "MUTE":
                self.mute = not self.mute
                self.status_queue.flush(
                    self.gen_status(self.mute and "mute" or "default"))
            elif cmd.keyword == "VOL DOWN" or cmd.keyword == "VOL UP":
                self.volume += cmd.keyword == "VOL DOWN" and -1 or +1
                self.status_queue.flush(self.gen_status("default"))
                self.status_queue.add_relative(3, self.gen_status("volume"))
        print("->", self.status())