def __init__(self):

        super(DfrobotBoard, self).__init__()

        # pin mappings
        self.pin_mappings = PinMappings(
            buzzer_pin=15,
            button_pin=16,
            rotary_pin=3,
            screen_register_select_pin=8,
            screen_enable_pin=9,
            screen_data_0_pin=4,
            screen_data_1_pin=5,
            screen_data_2_pin=6,
            screen_data_3_pin=7,
            screen_analog_input_pin=0
        )

        if HARDWARE_CONFIG.platform == KNOWN_PLATFORMS.firmata:
            addSubplatform(GENERIC_FIRMATA, "/dev/ttyACM0")
            self.pin_mappings += 512

        self.screen = SAINSMARTKS(
            self.pin_mappings.screen_register_select_pin,
            self.pin_mappings.screen_enable_pin,
            self.pin_mappings.screen_data_0_pin,
            self.pin_mappings.screen_data_1_pin,
            self.pin_mappings.screen_data_2_pin,
            self.pin_mappings.screen_data_3_pin,
            self.pin_mappings.screen_analog_input_pin
        )

        self.buzzer = Gpio(self.pin_mappings.buzzer_pin)
        self.rotary = Rotary(self.pin_mappings.rotary_pin)
        self.button = Button(self.pin_mappings.button_pin)

        self.buzzer.dir(DIR_OUT)

        self.rotary_value = 0
        self.button_state = False
    def __init__(self):

        super(GroveBoard, self).__init__()

        # pin mappings
        self.pin_mappings = PinMappings(buzzer_pin=6,
                                        button_pin=5,
                                        rotary_pin=0,
                                        i2c_bus=6)

        if HARDWARE_CONFIG.platform == KNOWN_PLATFORMS.firmata:
            addSubplatform(GENERIC_FIRMATA, "/dev/ttyACM0")
            self.pin_mappings += 512
            self.pin_mappings.i2c_bus = 512

        self.screen = Jhd1313m1(self.pin_mappings.i2c_bus, 0x3E, 0x62)
        self.buzzer = Gpio(self.pin_mappings.buzzer_pin)
        self.rotary = Rotary(self.pin_mappings.rotary_pin)
        self.button = Button(self.pin_mappings.button_pin)

        self.buzzer.dir(DIR_OUT)

        self.rotary_value = 0
        self.button_state = False
    def __init__(self):

        super(GroveBoard, self).__init__()

        # pin mappings
        self.pin_mappings = PinMappings(buzzer_pin=6, button_pin=5, rotary_pin=0, i2c_bus=6)

        if HARDWARE_CONFIG.platform == KNOWN_PLATFORMS.firmata:
            addSubplatform(GENERIC_FIRMATA, "/dev/ttyACM0")
            self.pin_mappings += 512
            self.pin_mappings.i2c_bus = 512

        self.screen = Jhd1313m1(self.pin_mappings.i2c_bus, 0x3E, 0x62)
        self.buzzer = Gpio(self.pin_mappings.buzzer_pin)
        self.rotary = Rotary(self.pin_mappings.rotary_pin)
        self.button = Button(self.pin_mappings.button_pin)

        self.buzzer.dir(DIR_OUT)

        self.rotary_value = 0
        self.button_state = False
    def __init__(self):

        super(DfrobotBoard, self).__init__()

        # pin mappings
        self.pin_mappings = PinMappings(
            buzzer_pin=15,
            button_pin=16,
            rotary_pin=3,
            screen_register_select_pin=8,
            screen_enable_pin=9,
            screen_data_0_pin=4,
            screen_data_1_pin=5,
            screen_data_2_pin=6,
            screen_data_3_pin=7,
            screen_analog_input_pin=0,
        )

        if HARDWARE_CONFIG.platform == KNOWN_PLATFORMS.firmata:
            addSubplatform(GENERIC_FIRMATA, "/dev/ttyACM0")
            self.pin_mappings += 512

        self.screen = SAINSMARTKS(
            self.pin_mappings.screen_register_select_pin,
            self.pin_mappings.screen_enable_pin,
            self.pin_mappings.screen_data_0_pin,
            self.pin_mappings.screen_data_1_pin,
            self.pin_mappings.screen_data_2_pin,
            self.pin_mappings.screen_data_3_pin,
            self.pin_mappings.screen_analog_input_pin,
        )

        self.buzzer = Gpio(self.pin_mappings.buzzer_pin)
        self.rotary = Rotary(self.pin_mappings.rotary_pin)
        self.button = Button(self.pin_mappings.button_pin)

        self.buzzer.dir(DIR_OUT)

        self.rotary_value = 0
        self.button_state = False
class DfrobotBoard(Board):
    """
    Board class for drobot hardware.
    """
    def __init__(self):

        super(DfrobotBoard, self).__init__()

        # pin mappings
        self.pin_mappings = PinMappings(buzzer_pin=15,
                                        button_pin=16,
                                        rotary_pin=3,
                                        screen_register_select_pin=8,
                                        screen_enable_pin=9,
                                        screen_data_0_pin=4,
                                        screen_data_1_pin=5,
                                        screen_data_2_pin=6,
                                        screen_data_3_pin=7,
                                        screen_analog_input_pin=0)

        if HARDWARE_CONFIG.platform == KNOWN_PLATFORMS.firmata:
            addSubplatform(GENERIC_FIRMATA, "/dev/ttyACM0")
            self.pin_mappings += 512

        self.screen = LCDKS(self.pin_mappings.screen_register_select_pin,
                            self.pin_mappings.screen_enable_pin,
                            self.pin_mappings.screen_data_0_pin,
                            self.pin_mappings.screen_data_1_pin,
                            self.pin_mappings.screen_data_2_pin,
                            self.pin_mappings.screen_data_3_pin,
                            self.pin_mappings.screen_analog_input_pin)

        self.buzzer = Gpio(self.pin_mappings.buzzer_pin)
        self.rotary = Rotary(self.pin_mappings.rotary_pin)
        self.button = Button(self.pin_mappings.button_pin)

        self.buzzer.dir(DIR_OUT)

        self.rotary_value = 0
        self.button_state = False

    def update_hardware_state(self):
        """
        Update hardware state.
        """

        current_rotary_value = self.read_rotary()
        if current_rotary_value != self.rotary_value:
            self.trigger_hardware_event(ROTARY, current_rotary_value)
            self.rotary_value = current_rotary_value

        current_button_state = self.button.value()
        if current_button_state != self.button_state:
            if not current_button_state:
                self.trigger_hardware_event(BUTTON_RELEASED)
            self.button_state = current_button_state

    # hardware functions
    def start_buzzer(self):
        """
        Start the hardware buzzer.
        """

        self.buzzer.write(1)

    def stop_buzzer(self):
        """
        Stop the hardware buzzer.
        """

        self.buzzer.write(0)

    def read_rotary(self):
        """
        Read rotary value.
        """

        return self.rotary.abs_value()

    def write_message(self, message, line=0):
        """
        Write message to LCD screen.
        """

        message = message.ljust(16)
        self.screen.setCursor(line, 0)
        self.screen.write(message)

    def change_background(self, color):
        """
        Change LCD screen background color.
        No effect on the dfrobot.
        """

        pass

    def change_brightness(self, value):
        """
        Change LCD screen brightness.
        Only supports on (value < 512) and off (value >= 512) on the dfrobot.
        """

        if value < 512:
            self.screen.displayOff()
        else:
            self.screen.displayOn()
class DfrobotBoard(Board):

    """
    Board class for drobot hardware.
    """

    def __init__(self):

        super(DfrobotBoard, self).__init__()

        # pin mappings
        self.pin_mappings = PinMappings(
            buzzer_pin=15,
            button_pin=16,
            rotary_pin=3,
            screen_register_select_pin=8,
            screen_enable_pin=9,
            screen_data_0_pin=4,
            screen_data_1_pin=5,
            screen_data_2_pin=6,
            screen_data_3_pin=7,
            screen_analog_input_pin=0,
        )

        if HARDWARE_CONFIG.platform == KNOWN_PLATFORMS.firmata:
            addSubplatform(GENERIC_FIRMATA, "/dev/ttyACM0")
            self.pin_mappings += 512

        self.screen = SAINSMARTKS(
            self.pin_mappings.screen_register_select_pin,
            self.pin_mappings.screen_enable_pin,
            self.pin_mappings.screen_data_0_pin,
            self.pin_mappings.screen_data_1_pin,
            self.pin_mappings.screen_data_2_pin,
            self.pin_mappings.screen_data_3_pin,
            self.pin_mappings.screen_analog_input_pin,
        )

        self.buzzer = Gpio(self.pin_mappings.buzzer_pin)
        self.rotary = Rotary(self.pin_mappings.rotary_pin)
        self.button = Button(self.pin_mappings.button_pin)

        self.buzzer.dir(DIR_OUT)

        self.rotary_value = 0
        self.button_state = False

    def update_hardware_state(self):

        """
        Update hardware state.
        """

        current_rotary_value = self.read_rotary()
        if current_rotary_value != self.rotary_value:
            self.trigger_hardware_event(ROTARY, current_rotary_value)
            self.rotary_value = current_rotary_value

        current_button_state = self.button.value()
        if current_button_state != self.button_state:
            if not current_button_state:
                self.trigger_hardware_event(BUTTON_RELEASED)
            self.button_state = current_button_state

    # hardware functions
    def start_buzzer(self):

        """
        Start the hardware buzzer.
        """

        self.buzzer.write(1)

    def stop_buzzer(self):

        """
        Stop the hardware buzzer.
        """

        self.buzzer.write(0)

    def read_rotary(self):

        """
        Read rotary value.
        """

        return self.rotary.abs_value()

    def write_message(self, message, line=0):

        """
        Write message to LCD screen.
        """

        message = message.ljust(16)
        self.screen.setCursor(line, 0)
        self.screen.write(message)

    def change_background(self, color):

        """
        Change LCD screen background color.
        No effect on the dfrobot.
        """

        pass

    def change_brightness(self, value):

        """
        Change LCD screen brightness.
        Only supports on (value < 512) and off (value >= 512) on the dfrobot.
        """

        if value < 512:
            self.screen.displayOff()
        else:
            self.screen.displayOn()
class GroveBoard(Board):
    """
    Board class for Grove hardware.
    """
    def __init__(self):

        super(GroveBoard, self).__init__()

        # pin mappings
        self.pin_mappings = PinMappings(buzzer_pin=6,
                                        button_pin=5,
                                        rotary_pin=0,
                                        i2c_bus=6)

        if HARDWARE_CONFIG.platform == KNOWN_PLATFORMS.firmata:
            addSubplatform(GENERIC_FIRMATA, "/dev/ttyACM0")
            self.pin_mappings += 512
            self.pin_mappings.i2c_bus = 512

        self.screen = Jhd1313m1(self.pin_mappings.i2c_bus, 0x3E, 0x62)
        self.buzzer = Gpio(self.pin_mappings.buzzer_pin)
        self.rotary = Rotary(self.pin_mappings.rotary_pin)
        self.button = Button(self.pin_mappings.button_pin)

        self.buzzer.dir(DIR_OUT)

        self.rotary_value = 0
        self.button_state = False

    def update_hardware_state(self):
        """
        Update hardware state.
        """

        current_rotary_value = self.read_rotary()
        if current_rotary_value != self.rotary_value:
            self.trigger_hardware_event(ROTARY, current_rotary_value)
            self.rotary_value = current_rotary_value

        current_button_state = self.button.value()
        if current_button_state != self.button_state:
            if not current_button_state:
                self.trigger_hardware_event(BUTTON_RELEASED)
            self.button_state = current_button_state

    # hardware functions
    def start_buzzer(self):
        """
        Start the hardware buzzer.
        """

        self.buzzer.write(1)

    def stop_buzzer(self):
        """
        Stop the hardware buzzer.
        """

        self.buzzer.write(0)

    def read_rotary(self):
        """
        Read rotary value.
        """

        return self.rotary.abs_value()

    def write_message(self, message, line=0):
        """
        Write message to LCD screen.
        """

        message = message.ljust(16)
        self.screen.setCursor(line, 0)
        self.screen.write(message)

    def change_background(self, color):
        """
        Change LCD screen background color.
        """

        colors = {
            "red": lambda: self.screen.setColor(255, 0, 0),
            "purple": lambda: self.screen.setColor(255, 0, 255),
            "blue": lambda: self.screen.setColor(0, 0, 255),
            "green": lambda: self.screen.setColor(0, 255, 0),
            "yellow": lambda: self.screen.setColor(255, 255, 0),
            "white": lambda: self.screen.setColor(255, 255, 255)
        }
        colors.get(color, colors["white"])()

    def change_brightness(self, value):
        """
        Change LCD screen brightness.
        """

        start = 0
        end = 1020
        value = int(floor((value - start) / end * 255))
        value = 0 if value < 0 else 255 if value > 255 else value
        self.screen.setColor(value, value, value)
class GroveBoard(Board):

    """
    Board class for Grove hardware.
    """

    def __init__(self):

        super(GroveBoard, self).__init__()

        # pin mappings
        self.pin_mappings = PinMappings(buzzer_pin=6, button_pin=5, rotary_pin=0, i2c_bus=6)

        if HARDWARE_CONFIG.platform == KNOWN_PLATFORMS.firmata:
            addSubplatform(GENERIC_FIRMATA, "/dev/ttyACM0")
            self.pin_mappings += 512
            self.pin_mappings.i2c_bus = 512

        self.screen = Jhd1313m1(self.pin_mappings.i2c_bus, 0x3E, 0x62)
        self.buzzer = Gpio(self.pin_mappings.buzzer_pin)
        self.rotary = Rotary(self.pin_mappings.rotary_pin)
        self.button = Button(self.pin_mappings.button_pin)

        self.buzzer.dir(DIR_OUT)

        self.rotary_value = 0
        self.button_state = False

    def update_hardware_state(self):

        """
        Update hardware state.
        """

        current_rotary_value = self.read_rotary()
        if current_rotary_value != self.rotary_value:
            self.trigger_hardware_event(ROTARY, current_rotary_value)
            self.rotary_value = current_rotary_value

        current_button_state = self.button.value()
        if current_button_state != self.button_state:
            if not current_button_state:
                self.trigger_hardware_event(BUTTON_RELEASED)
            self.button_state = current_button_state

    # hardware functions
    def start_buzzer(self):

        """
        Start the hardware buzzer.
        """

        self.buzzer.write(1)

    def stop_buzzer(self):

        """
        Stop the hardware buzzer.
        """

        self.buzzer.write(0)

    def read_rotary(self):

        """
        Read rotary value.
        """

        return self.rotary.abs_value()

    def write_message(self, message, line=0):

        """
        Write message to LCD screen.
        """

        message = message.ljust(16)
        self.screen.setCursor(line, 0)
        self.screen.write(message)

    def change_background(self, color):

        """
        Change LCD screen background color.
        """

        colors = {
            "red": lambda: self.screen.setColor(255, 0, 0),
            "purple": lambda: self.screen.setColor(255, 0, 255),
            "blue": lambda: self.screen.setColor(0, 0, 255),
            "green": lambda: self.screen.setColor(0, 255, 0),
            "yellow": lambda: self.screen.setColor(255, 255, 0),
            "white": lambda: self.screen.setColor(255, 255, 255),
        }
        colors.get(color, colors["white"])()

    def change_brightness(self, value):

        """
        Change LCD screen brightness.
        """

        start = 0
        end = 1020
        value = int(floor((value - start) / end * 255))
        value = 0 if value < 0 else 255 if value > 255 else value
        self.screen.setColor(value, value, value)