示例#1
0
文件: gui.py 项目: marcio-pessoa/xc
 def start_screen(self):
     """
     description:
     """
     # global pygame
     echo.infoln("Screen...")
     # Set screen resolution
     self.screen_resolution = [
         int(s) for s in self.screen_size.split('x') if s.isdigit()
     ]
     # Check for minimum resolution
     if (self.screen_resolution[0] < 480) or \
        (self.screen_resolution[1] < 320):
         self.screen_resolution = (480, 320)
     self.screen_resolution[0] -= 1
     self.screen_resolution[1] -= 1
     echo.infoln(
         "Size: " + str(self.screen_resolution[0] + 1) + 'x' +
         str(self.screen_resolution[1] + 1) + ' px', 1)
     echo.infoln("Refresh rate: " + str(self.screen_rate) + ' FPS', 1)
     # Positioning
     os.environ['SDL_VIDEO_CENTERED'] = '1'
     # Initialise screen
     pygame.init()  # pylint: disable=no-member
     self.screen = pygame.display.set_mode(self.screen_resolution)
     if self.screen_full:
         pygame.display.toggle_fullscreen()
     # Window caption
     pygame.display.set_caption(self.window_title)
     # Checking fonts
     echo.debugln('Checking fonts...', 1)
     for ttf_name in ['Digital Readout Thick Upright', 'Ubuntu']:
         ttf_path = pygame.font.match_font(ttf_name)
         if ttf_path is None:
             echo.erroln('TrueType font missing.')
             echo.infoln(
                 '\"' + str(ttf_name) + '\" not found (' + str(ttf_path) +
                 ')', 2)
     # Background
     self.background = pygame.Surface(self.screen.get_size())
     self.background.fill([0, 0, 0])  # Black
     # Controls area
     self.controls = pygame.Surface([120, 240])
     # Object area
     self.object_area = pygame.Surface(
         [self.screen.get_size()[0] - 65,
          self.screen.get_size()[1] - 70])
     # Status bar
     self.status_bar = pygame.Surface([self.screen.get_size()[0], 16])
     # Clockling
     echo.debugln('Clockling...', 1)
     self.clock = pygame.time.Clock()
     # Screensaver
     self.screensaver = Screensaver(self.screen)
     self.screensaver_timer = Timer(1000 * self.screensaver_time,
                                    'COUNTDOWN')
     if not self.screensaver_enable:
         self.screensaver_timer.disable()
示例#2
0
 def start_x86_64(self):
     """
     description:
     """
     self.timer = Timer(1000)
     # Temperature sensor
     status = 'Absent'
     try:
         if self.data[self.name]["resources"]["temperature_sensor"]:
             self.temperature = 0
             status = 'Present'
     except BaseException:
         pass
     echo.debugln('Temperature sensor: ' + status, 1)
示例#3
0
文件: gui.py 项目: marcio-pessoa/xc
 def __init__(self, data):  # pylint: disable=too-many-statements
     self.__work_dir = os.path.dirname(os.path.realpath(__file__))
     self.__work_dir = os.path.join(self.__work_dir, '../')
     self.__img_dir = os.path.join(self.__work_dir, 'images')
     self.screen_full = False
     self.screen_size = "480x320"
     self.screen_rate = 30
     self.screensaver_time = 60
     self.screensaver_type = 'black'
     self.screensaver_enable = False
     self.screen = None
     self.screen_resolution = None
     self.screensaver = None
     self.screensaver_timer = None
     self.controls = None
     self.object_area = None
     self.status_bar = None
     self.clock = None
     self.background = None
     self.host = None
     self.session = None
     self.running = None
     self.device = None
     self.device_timer = Timer(1000)
     self.connected_devices = None
     self.was_connected = None
     self.__joystick = None
     self.joyicon = None
     self.control_joystick_button = None
     self.__keyboard = None
     self.keyboard = None
     self.control_keyboard_button = None
     self.__mouse = None
     self.mouse = None
     self.control_mouse_button = None
     self.__touch = None
     self.touch = None
     self.control_touch_button = None
     self.ctrl_touch_delay = None
     self.control_touch_delay = None
     self.control_touch_enable = None
     self.control_touch_speed = None
     self.control_touch_visible = None
     self.window_caption = None
     self.window_title = None
     self.load(data)
     self.reset()
示例#4
0
 def __init__(self):
     self.__enable = False
     self.__factor = 1
     self.__scan_time = 1000  # milliseconds
     self.__scan_timer = Timer(self.__scan_time)
     self.__joystick = None
     self.__mapping = {}
     self.reset()
示例#5
0
 def start_armv7l(self):
     """
     description:
     """
     try:
         from fan import Fan
     except ImportError as err:
         echo.erroln("Could not load module. " + str(err))
         sys.exit(True)
     self.timer = Timer(1000)
     # Temperature sensor
     status = 'Absent'
     try:
         if self.data[self.name]["resources"]["temperature_sensor"]:
             self.temperature = 0
             status = 'Present'
     except BaseException:
         pass
     echo.debugln('Temperature sensor: ' + status, 1)
     # Status LED
     status = 'Absent'
     try:
         if self.data[self.name]["resources"]["status_led"]:
             from tools.signal import SigGen
             GPIO.setup(33, GPIO.OUT)
             self.status_led = GPIO.PWM(33, 50)
             self.status_led.start(0)
             self.status_signal = SigGen()
             self.status_signal.period(1000)
             status = 'Present'
     except BaseException:
         pass
     echo.infoln('Status LED: ' + status, 1)
     # Fan
     status = 'Absent'
     try:
         if self.data[self.name]["resources"]["fan"]:
             self.fan = Fan(32, 22, max_speed=2000)
             self.fan.set_limits(40, 60)
             self.fan_speed = 0
             status = 'Present'
     except BaseException:
         pass
     echo.infoln('Fan: ' + status, 1)
示例#6
0
文件: fan.py 项目: marcio-pessoa/xc
 def __init__(self, write_pin, read_pin=None, max_speed=3000):
     self.read_pin = read_pin  # Pin number
     self.write_pin = write_pin  # Pin number
     self.max_speed = max_speed  # RPM
     self.speed = 100  # Initial speed
     self.is_sensor_present = False
     self.rpm = 0
     self.counter_rpm = 0
     self.sample_rate = 30  # Sample rate (per minute)
     self.delta_t = 60.0 / self.sample_rate * 1000  # Interval (per seconds)
     self.timer = Timer(self.delta_t)
     self.bounce = 1000 / (self.max_speed * 2 / 60)  # Bounce time
     self.limit_min = 0
     self.limit_max = 100
     # setmode
     # Available modes:
     #     GPIO.BOARD: Board numbering scheme. The pin numbers follow the pin
     #                 numbers on header P1.
     #     GPIO.BCM: Broadcom chip-specific pin numbers. These pin numbers
     #               follow the lower-level numbering system defined by the
     #               Raspberry Pis Broadcom-chip brain.
     GPIO.setmode(GPIO.BOARD)
     # Set fan control pin
     GPIO.setup(self.write_pin, GPIO.OUT)
     # Set PWM control
     self.fan_controller = GPIO.PWM(self.write_pin, self.speed)
     self.fan_controller.start(self.speed)
     if self.read_pin is not None:
         self.is_sensor_present = True
         # Set fan sensor pin
         # pull_up_down: Internal Pull-ups and Pull-down resistors.
         # Available options:
         #     GPIO.PUD_UP: Pull up
         #     GPIO.PUD_DOWN: Pull down
         GPIO.setup(self.read_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
         # Add interrupt detection
         GPIO.add_event_detect(self.read_pin,
                               GPIO.RISING,
                               callback=self.counter,
                               bouncetime=self.bounce)
示例#7
0
文件: gui.py 项目: marcio-pessoa/xc
 def start_objects(self):
     """
     description:
     """
     for i in self.device.get_objects():
         i["image"] = Image(
             self.object_area,
             os.path.join(self.__img_dir, i["picture"]["file"]),
             eval(i["picture"]["split"]))
         i["boolean"] = i["default"] == "on"
         # infoln('ID: ' + str(i["id"]) + ", default: " + str(i["default"]))
         i["source"] = ''
         i["factor"] = '1'
         i["button"] = Button(i["image"], eval(i["picture"]["position"]),
                              [65, 50], i["boolean"])
         try:
             i["timer"] = Timer(i["delay"])
         except BaseException:
             i["timer"] = Timer(20)
         i["state"] = i["default"]
     if self.device.get_objects():
         echo.infoln('Objects...')
         echo.infoln('Imported: ' + str(len(self.device.get_objects())), 1)
示例#8
0
    def period(self, time=False):
        """
        description: Set scan period

        parameters:
          time: scan time period (integer >= 1000)

        returns:
          int: scan time period
        """
        if time >= 1000:
            self.__scan_time = time
            self.__scan_timer = Timer(self.__scan_time)
        return self.__scan_time
示例#9
0
文件: fan.py 项目: marcio-pessoa/xc
class Fan():  # pylint: disable=too-many-instance-attributes
    """
    description: Fan speed control.

        Fan (write_pin, read_pin)

    parameters:
        write_pin: Arduino LED connected to PWM motor controller
        read_pin: Arduino pin connected to motor sensor pin

    returns:
        void
    """

    __version__ = 0.3

    def __init__(self, write_pin, read_pin=None, max_speed=3000):
        self.read_pin = read_pin  # Pin number
        self.write_pin = write_pin  # Pin number
        self.max_speed = max_speed  # RPM
        self.speed = 100  # Initial speed
        self.is_sensor_present = False
        self.rpm = 0
        self.counter_rpm = 0
        self.sample_rate = 30  # Sample rate (per minute)
        self.delta_t = 60.0 / self.sample_rate * 1000  # Interval (per seconds)
        self.timer = Timer(self.delta_t)
        self.bounce = 1000 / (self.max_speed * 2 / 60)  # Bounce time
        self.limit_min = 0
        self.limit_max = 100
        # setmode
        # Available modes:
        #     GPIO.BOARD: Board numbering scheme. The pin numbers follow the pin
        #                 numbers on header P1.
        #     GPIO.BCM: Broadcom chip-specific pin numbers. These pin numbers
        #               follow the lower-level numbering system defined by the
        #               Raspberry Pis Broadcom-chip brain.
        GPIO.setmode(GPIO.BOARD)
        # Set fan control pin
        GPIO.setup(self.write_pin, GPIO.OUT)
        # Set PWM control
        self.fan_controller = GPIO.PWM(self.write_pin, self.speed)
        self.fan_controller.start(self.speed)
        if self.read_pin is not None:
            self.is_sensor_present = True
            # Set fan sensor pin
            # pull_up_down: Internal Pull-ups and Pull-down resistors.
            # Available options:
            #     GPIO.PUD_UP: Pull up
            #     GPIO.PUD_DOWN: Pull down
            GPIO.setup(self.read_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
            # Add interrupt detection
            GPIO.add_event_detect(self.read_pin,
                                  GPIO.RISING,
                                  callback=self.counter,
                                  bouncetime=self.bounce)

    def counter(self):
        """
        description: Just a counter.

        parameters:
            none

        returns:
            bool
        """
        if not self.is_sensor_present:
            self.counter_rpm = 0
            return True
        # Count
        self.counter_rpm += 1
        if self.timer.check():
            self.rpm = int(self.counter_rpm / self.delta_t * 1000 * 60 / 2.0)
            self.counter_rpm = 0
        return False

    def write_speed(self, speed):
        """
        description: Change fan speed value.

            fan.speedWrite(int percent_speed)

        parameters:
            percent_speed: Fan percent speed

        returns:
            false: invalid input
            true: no errors
        """
        # Check input limits
        if (speed < 0 or speed > 100):
            return True
        self.speed = speed
        # Write to PWM
        self.fan_controller.ChangeDutyCycle(self.speed)
        return False

    def set_limits(self, minimum, maximum):
        """
        description:
        """
        self.limit_min = minimum
        self.limit_max = maximum

    def auto_speed(self, x_input):
        """
        description:
        """
        speed = amap(constrain(x_input, self.limit_min, self.limit_max),
                     self.limit_min, self.limit_max, 0, 100)
        self.write_speed(speed)

    def read_speed(self):
        """
         * Description
         *   .

         *   a_led.blink()


         * Parameters
         *   none


         * Returns
         *   false: if the last state was not modified
         *   true: if the last state was modified
        """
        return self.speed

    def read_rpm(self):
        """
        description:
        """
        return self.rpm

    def stop(self):
        """
        description:
        """
        return self.fan_controller.stop()

    def cleanup(self):
        """
        description:
        """
        self.stop()
        return GPIO.cleanup()
示例#10
0
class HostProperties:  # pylint: disable=too-many-instance-attributes
    """
    description:
    """

    __version__ = 0.5

    def __init__(self, data):
        self.name = ''
        self.machine = ''
        self.architecture = ''
        self.processor = ''
        self.core = 0
        self.memory = 0
        self.memory_used = 0
        self.system = ''
        self.distribution = ''
        self.distribution_version = ''
        self.python_version = ''
        self.temperature = None
        self.status_led = None
        self.status_signal = None
        self.fan_speed = None
        self.fan = None
        self.timer = None
        self.load(data)
        self.set()

    def load(self, data):
        """
        description:
        """
        self.data = data

    def set(self):
        """
        description:
        """
        # self.reset()
        self.name = platform.node()
        self.machine = platform.machine()
        self.architecture = platform.architecture()[0]
        self.processor = platform.processor()
        self.core = os.sysconf("SC_NPROCESSORS_ONLN")
        self.memory = int(
            round(float(virtual_memory().total) / 1024 / 1024 / 1024))
        self.memory_used = virtual_memory().percent
        self.system = platform.system()
        self.distribution = distro.linux_distribution()[0]
        self.distribution_version = distro.linux_distribution()[1]
        self.python_version = platform.python_version()
        self.profile = 'generic'
        if self.name in self.data:
            self.profile = self.name
        else:
            self.profile = 'generic'

    def info(self):
        """
        description:
        """
        echo.infoln("Host...")
        echo.debugln("Profile: " + self.profile, 1)
        echo.infoln("Name: " + self.name, 1)
        echo.debugln(
            "Machine: " + self.machine + " (" + self.architecture + ")", 1)
        echo.debugln("Processor: " + self.processor, 1)
        echo.debug("Core", 1)
        if self.core > 1:
            echo.debug("s")
        echo.debugln(": " + str(self.core))
        echo.debugln(
            "Memory: " + str(self.memory) + "GB (used: " +
            str(self.memory_used) + "%)", 1)
        echo.debug("Operating system: " + self.system, 1)
        if platform.system() == 'Linux':
            echo.debugln(" (" + self.distribution + " " +
                         self.distribution_version + ")")
        echo.debugln("Python: " + self.python_version, 1)

    def run(self):
        """
        description:
        """
        if self.machine == 'armv7l':
            self.run_armv7l()
        if self.machine == 'x86_64':
            self.run_x86_64()

    def start_x86_64(self):
        """
        description:
        """
        self.timer = Timer(1000)
        # Temperature sensor
        status = 'Absent'
        try:
            if self.data[self.name]["resources"]["temperature_sensor"]:
                self.temperature = 0
                status = 'Present'
        except BaseException:
            pass
        echo.debugln('Temperature sensor: ' + status, 1)

    def start(self):
        """
        description:
        """
        if self.machine == 'armv7l':
            self.start_armv7l()
        if self.machine == 'x86_64':
            self.start_x86_64()

    def run_x86_64(self):
        """
        description:
        """
        if not self.timer.check():
            return False
        # Temperature sensor
        try:
            if self.data[self.name]["resources"]["temperature_sensor"]:
                from psutil import sensors_temperatures
                payload = str(sensors_temperatures()['acpitz']).split(',')[1]
                temperature = re.sub(r' [a-z]*=', '', payload)
                self.temperature = str("{:1.0f} C".format(float(temperature)))
        except BaseException:
            pass
        return False

    def run_armv7l(self):
        """
        description:
        """
        # Blink Status LED
        try:
            if self.data[self.name]["resources"]["status_led"]:
                self.status_led.ChangeDutyCycle(self.status_signal.sine() *
                                                100)
        except BaseException:
            pass
        # Check sensors
        if not self.timer.check():
            return False
        # Temperature sensor
        try:
            if self.data[self.name]["resources"]["temperature_sensor"]:
                temp = os.popen("vcgencmd measure_temp").readline()
                temp = temp.replace("temp=", "")
                temp = temp.replace("\'C", "")
                self.temperature = str("{:1.0f} C".format(float(temp)))
        except BaseException:
            pass
        # Fan speed
        try:
            if self.data[self.name]["resources"]["temperature_sensor"] and \
               self.data[self.name]["resources"]["fan"]:
                self.fan.auto_speed(self.temperature)
                self.fan_speed = str("{:1.1f} RPM".format(
                    float(self.fan.read_rpm())))
        except BaseException:
            pass
        return False

    def status_armv7l(self):
        """
        description:
        """
        status = ''
        self.run_armv7l()
        try:
            if self.data[self.name]["resources"]["temperature_sensor"]:
                status = self.temperature
        except BaseException:
            pass
        try:
            if self.data[self.name]["resources"]["temperature_sensor"] and \
               self.data[self.name]["resources"]["fan"]:
                status += '    ' + str(self.fan_speed) + ' RPM'
        except BaseException:
            pass
        return status

    def status_x86_64(self):
        """
        description:
        """
        status = ''
        self.run_x86_64()
        try:
            if self.data[self.name]["resources"]["temperature_sensor"]:
                status = self.temperature
        except BaseException:
            pass
        return status

    def status(self):
        """
        description:
        """
        if self.machine == 'armv7l':
            return self.status_armv7l()
        if self.machine == 'x86_64':
            return self.status_x86_64()
        return ''

    def start_armv7l(self):
        """
        description:
        """
        try:
            from fan import Fan
        except ImportError as err:
            echo.erroln("Could not load module. " + str(err))
            sys.exit(True)
        self.timer = Timer(1000)
        # Temperature sensor
        status = 'Absent'
        try:
            if self.data[self.name]["resources"]["temperature_sensor"]:
                self.temperature = 0
                status = 'Present'
        except BaseException:
            pass
        echo.debugln('Temperature sensor: ' + status, 1)
        # Status LED
        status = 'Absent'
        try:
            if self.data[self.name]["resources"]["status_led"]:
                from tools.signal import SigGen
                GPIO.setup(33, GPIO.OUT)
                self.status_led = GPIO.PWM(33, 50)
                self.status_led.start(0)
                self.status_signal = SigGen()
                self.status_signal.period(1000)
                status = 'Present'
        except BaseException:
            pass
        echo.infoln('Status LED: ' + status, 1)
        # Fan
        status = 'Absent'
        try:
            if self.data[self.name]["resources"]["fan"]:
                self.fan = Fan(32, 22, max_speed=2000)
                self.fan.set_limits(40, 60)
                self.fan_speed = 0
                status = 'Present'
        except BaseException:
            pass
        echo.infoln('Fan: ' + status, 1)

    def get_control(self):
        """
        description:
        """
        try:
            return self.data[self.name]["control"]
        except BaseException:
            pass

    def get_screen(self):
        """
        description:
        """
        try:
            return self.data[self.name]["screen"]
        except BaseException:
            pass

    def get_screensaver(self):
        """
        description:
        """
        try:
            return self.data[self.name]["screensaver"]
        except BaseException:
            pass

    def stop(self):
        """
        description:
        """
        if self.machine == 'armv7l':
            self.stop_armv7l()
        if self.machine == 'x86_64':
            self.stop_x86_64()

    def stop_x86_64(self):  # pylint: disable=no-self-use
        """
        description:
        """
        return False

    def stop_armv7l(self):
        """
        description:
        """
        try:
            if self.data[self.name]["resources"]["status_led"]:
                self.status_led.stop()
        except BaseException:
            pass
        try:
            if self.data[self.name]["resources"]["fan"]:
                self.fan.stop()
        except BaseException:
            pass
        try:
            if self.data[self.name]["resources"]["status_led"] or \
               self.data[self.name]["resources"]["fan"]:
                GPIO.cleanup()
        except BaseException:
            pass
示例#11
0
文件: gui.py 项目: marcio-pessoa/xc
class Gui:  # pylint: disable=too-many-public-methods,too-many-instance-attributes
    """
    description:
    """

    __version__ = 0.20

    def __init__(self, data):  # pylint: disable=too-many-statements
        self.__work_dir = os.path.dirname(os.path.realpath(__file__))
        self.__work_dir = os.path.join(self.__work_dir, '../')
        self.__img_dir = os.path.join(self.__work_dir, 'images')
        self.screen_full = False
        self.screen_size = "480x320"
        self.screen_rate = 30
        self.screensaver_time = 60
        self.screensaver_type = 'black'
        self.screensaver_enable = False
        self.screen = None
        self.screen_resolution = None
        self.screensaver = None
        self.screensaver_timer = None
        self.controls = None
        self.object_area = None
        self.status_bar = None
        self.clock = None
        self.background = None
        self.host = None
        self.session = None
        self.running = None
        self.device = None
        self.device_timer = Timer(1000)
        self.connected_devices = None
        self.was_connected = None
        self.__joystick = None
        self.joyicon = None
        self.control_joystick_button = None
        self.__keyboard = None
        self.keyboard = None
        self.control_keyboard_button = None
        self.__mouse = None
        self.mouse = None
        self.control_mouse_button = None
        self.__touch = None
        self.touch = None
        self.control_touch_button = None
        self.ctrl_touch_delay = None
        self.control_touch_delay = None
        self.control_touch_enable = None
        self.control_touch_speed = None
        self.control_touch_visible = None
        self.window_caption = None
        self.window_title = None
        self.load(data)
        self.reset()

    def reset(self):
        """
        description:
        """
        self.device = DeviceProperties(self.data)
        self.window_title = 'xC'
        self.window_caption = 'xC - Axes Controller'
        self.was_connected = False
        self.connected_devices = 0

    def load(self, data):
        """
        description:
        """
        self.data = data

    def ctrl_joystick_start(self):
        """
        description:
        """
        self.__joystick = ControlJoystick()
        # Is supported?
        if 'joystick' in self.device.get_control():
            # Is enable?
            if 'enable' in self.device.get_control()['joystick']:
                if self.device.get_control()['joystick']['enable'] is True:
                    self.__joystick.enable()
            # Set factor
            if 'factor' in self.device.get_control()['joystick']:
                self.__joystick.factor(
                    self.device.get_control()['joystick']['factor'])
        # Start
        self.__joystick.start()
        self.__joystick.info()
        self.__joystick.mapping(self.device.get_objects())
        # Draw
        self.joyicon = Image(self.controls,
                             os.path.join(self.__img_dir, 'joystick.png'),
                             [2, 1])
        self.control_joystick_button = Button(self.joyicon, [0, 100], [5, 58],
                                              self.__joystick.state())

    def ctrl_keyboard_handle(self, event):  # pylint: disable=too-many-branches
        """
        description:
        """
        # Program behavior
        if event.type == KEYDOWN:  # pylint: disable=undefined-variable
            # Escape
            if event.key == K_ESCAPE:  # pylint: disable=undefined-variable
                self.running = False
            # Keyboard grab
            if event.key == K_F9:  # pylint: disable=undefined-variable
                self.control_keyboard_button.toggle()
            # Mouse grab
            if event.key == K_F10:  # pylint: disable=undefined-variable
                self.control_mouse_button.toggle()
            # Joystick grab
            if event.key == K_F11:  # pylint: disable=undefined-variable
                self.control_joystick_button.toggle()
            # Touch grab
            if event.key == K_F12:  # pylint: disable=undefined-variable
                self.control_touch_button.toggle()
            # Release controls
            if event.key == K_LALT:  # pylint: disable=undefined-variable
                self.control_keyboard_button.off()
                self.control_mouse_button.off()
                self.control_joystick_button.off()
                self.control_touch_button.off()
            self.__keyboard.state(self.control_keyboard_button.state())
            self.__mouse.state(self.control_mouse_button.state())
            self.__joystick.state(self.control_joystick_button.state())
            self.__touch.state(self.control_touch_button.state())
        # Object behavior
        self.__keyboard.handle(event)

    def ctrl_keyboard_start(self):
        """
        description:
        """
        self.__keyboard = ControlKeyboard()
        # Is supported?
        if 'keyboard' in self.device.get_control():
            # Is enable?
            if 'enable' in self.device.get_control()['keyboard']:
                if self.device.get_control()['keyboard']['enable'] is True:
                    self.__keyboard.enable()
            # Set delay
            if 'delay' in self.device.get_control()['keyboard']:
                self.__keyboard.delay(
                    self.device.get_control()['keyboard']['delay'])
            # Set interval
            if 'interval' in self.device.get_control()['keyboard']:
                self.__keyboard.delay(
                    self.device.get_control()['keyboard']['interval'])
        # Start
        self.__keyboard.start()
        self.__keyboard.info()
        self.__keyboard.mapping(self.device.get_objects())
        # Draw
        self.keyboard = Image(self.controls,
                              os.path.join(self.__img_dir, 'keyboard.png'),
                              [2, 1])
        self.control_keyboard_button = Button(self.keyboard, [0, 0], [5, 58],
                                              self.__keyboard.state())

    def ctrl_mouse_start(self):
        """
        description:
        """
        self.__mouse = ControlMouse()
        # Is supported?
        if 'mouse' in self.device.get_control():
            # Is enable?
            if 'enable' in self.device.get_control()['mouse']:
                if self.device.get_control()['mouse']['enable'] is True:
                    self.__mouse.enable()
            # Set factor
            if 'factor' in self.device.get_control()['mouse']:
                self.__mouse.factor(
                    self.device.get_control()['mouse']['factor'])
        # Start
        self.__mouse.start()
        self.__mouse.info()
        self.__mouse.mapping(self.device.get_objects())
        # Draw
        self.mouse = Image(self.controls,
                           os.path.join(self.__img_dir, 'mouse.png'), [2, 1])
        self.control_mouse_button = Button(self.mouse, [0, 50], [5, 58],
                                           self.__mouse.state())

    def ctrl_touch_handle(self, event):
        """
        description:
        """
        # Program behavior
        if event.type == MOUSEBUTTONUP:  # pylint: disable=undefined-variable
            # Set button
            self.control_keyboard_button.check(pygame.mouse.get_pos())
            self.control_mouse_button.check(pygame.mouse.get_pos())
            self.control_joystick_button.check(pygame.mouse.get_pos())
            self.control_touch_button.check(pygame.mouse.get_pos())
            # Set control
            self.__keyboard.state(self.control_keyboard_button.state())
            self.__mouse.state(self.control_mouse_button.state())
            self.__joystick.state(self.control_joystick_button.state())
            self.__touch.state(self.control_touch_button.state())
        # Object behavior
        self.__touch.handle(event)

    def ctrl_touch_start(self):
        """
        description:
        """
        self.__touch = ControlTouch()
        # Is supported?
        if 'touch' in self.device.get_control():
            # Is enable?
            if 'enable' in self.device.get_control()['touch']:
                if self.device.get_control()['touch']['enable'] is True:
                    self.__touch.enable()
            # Set visitility
            if 'visible' in self.host.get_control()['touch']:
                self.__touch.visible(
                    self.host.get_control()['touch']['visible'])
        # Start
        self.__touch.start()
        self.__touch.info()
        self.__touch.mapping(self.device.get_objects())
        # Draw
        self.touch = Image(self.controls,
                           os.path.join(self.__img_dir, 'touch.png'), [2, 1])
        self.control_touch_button = Button(self.touch, [0, 150], [5, 58],
                                           self.__touch.state())

    def start_session(self):
        """
        description:
        """
        self.session = Session(self.device.get_comm())
        self.session.info()
        self.session.start()
        if self.session.is_connected_serial():
            while not self.session.is_ready():
                continue
            # self.session.clear()
            for command in self.device.get_startup()["command"]:
                self.session.send_wait(command)
            self.was_connected = True

    def draw_device(self):
        """
        description:
        """
        # Device name
        font = pygame.font.SysFont('Ubuntu', 22)
        text = font.render(self.window_caption, True, (100, 100, 100))
        textpos = text.get_rect()
        textpos.centerx = self.background.get_rect().centerx
        textpos[1] += 10
        self.screen.blit(text, textpos)

    def stop_session(self):
        """
        description:
        """
        if not self.session.is_connected_serial():
            return
        echo.infoln('Session...')
        while not self.session.is_ready():
            continue
        echo.infoln('Terminating...', 1)
        for command in self.device.get_endup()["command"]:
            self.session.send_wait(command)
        self.session.stop()
        self.was_connected = False

    def stop_ctrl(self):
        """
        description:
        """
        self.__touch.disable()
        self.__joystick.disable()
        self.__mouse.disable()
        self.__keyboard.disable()

    def stop(self):
        """
        description:
        """
        self.stop_ctrl()
        self.stop_session()
        self.host.stop()
        pygame.quit()  # pylint: disable=no-member

    def draw_object(self):
        """
        description:
        """
        self.object_area.fill([0, 0, 0])  # Black
        for i in self.device.get_objects():
            i["button"].draw()
        self.screen.blit(self.object_area, [65, 50])

    def run(self):
        """
        description:
        """
        echo.infoln('Ready...')
        self.running = True
        while self.running:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:  # pylint: disable=no-member
                    self.running = False
                self.ctrl_check(event)
            self.draw()
            self.ctrl_handle()
            self.device_check()
        echo.infoln("Exiting...")
        self.stop()
        return False

    def ctrl_handle(self):
        """
        description:
        """
        # Objects
        for i in self.device.get_objects():
            if i["source"] == 'joystick':
                continue
            # Push button (pulse)
            if i["type"] == 'push-button' and \
               i["button"].get_state() and \
               i["timer"].check() and \
               self.session.is_connected():
                command = i["on"]["command"].replace('*', i["factor"])
                self.session.send_wait(command)
            # Switch
            elif i["type"] == 'switch' and \
                 i["button"].get_change() and \
                 self.session.is_connected():
                i["state"] = "on" if i["button"].get_state() else "off"
                command = i[i["state"]]["command"]
                self.session.send_wait(command)

    def ctrl_check(self, event):
        """
        description:
        """
        self.screensaver_timer.reset()
        if self.screensaver.running:
            self.screensaver.stop()
            return
        self.ctrl_keyboard_handle(event)
        self.__mouse.handle(event)
        self.__joystick.handle(event)
        self.ctrl_touch_handle(event)
        self.ctrl_handle()

    def draw_ctrl(self):
        """
        description:
        """
        self.controls.fill([0, 0, 0])  # Black
        self.control_keyboard_button.draw()
        self.control_mouse_button.draw()
        self.control_joystick_button.draw()
        self.control_touch_button.draw()
        self.screen.blit(self.controls, (5, 58))

    def draw_screensaver(self):
        """
        description:
        """
        if self.screensaver_timer.check() and not self.screensaver.running:
            self.screensaver.style(self.screensaver_type)
            self.screensaver.start()
        if self.screensaver.running:
            self.screensaver.run()

    def draw(self):
        """
        description:
        """
        self.screen.blit(self.background, (0, 0))
        self.draw_ctrl()
        self.draw_object()
        self.draw_device()
        self.draw_status()
        self.draw_screensaver()
        self.clock.tick(self.screen_rate)
        pygame.display.flip()

    def start_host(self):
        """
        description:
        """
        self.host = HostProperties(self.data["host"])
        self.host.info()
        echo.debugln("pygame: " + pygame.version.ver, 1)
        self.host.start()
        # Get Screen parameters
        try:
            self.screen_full = self.host.get_screen()["full"]
            self.screen_size = self.host.get_screen()["size"]
            self.screen_rate = self.host.get_screen()["rate"]
        except BaseException:
            pass
        # Get Screensaver parameters
        try:
            self.screensaver_time = self.host.get_screensaver() \
                .get('time', self.screensaver_time)
            if self.screensaver_time < 1:
                self.screensaver_time = 1
            self.screensaver_type = self.host.get_screensaver() \
                .get('type', self.screensaver_type)
            self.screensaver_enable = self.host.get_screensaver() \
                .get('enable', self.screensaver_enable)
        except BaseException:
            pass

    def start_objects(self):
        """
        description:
        """
        for i in self.device.get_objects():
            i["image"] = Image(
                self.object_area,
                os.path.join(self.__img_dir, i["picture"]["file"]),
                eval(i["picture"]["split"]))
            i["boolean"] = i["default"] == "on"
            # infoln('ID: ' + str(i["id"]) + ", default: " + str(i["default"]))
            i["source"] = ''
            i["factor"] = '1'
            i["button"] = Button(i["image"], eval(i["picture"]["position"]),
                                 [65, 50], i["boolean"])
            try:
                i["timer"] = Timer(i["delay"])
            except BaseException:
                i["timer"] = Timer(20)
            i["state"] = i["default"]
        if self.device.get_objects():
            echo.infoln('Objects...')
            echo.infoln('Imported: ' + str(len(self.device.get_objects())), 1)

    def device_set(self, device_id):
        """
        description:
        """
        self.device.set(device_id)

    def device_check(self):
        """
        description:
        """
        if not self.device_timer.check():
            return False
        # Reset all data if device was unpluged.
        if not self.session.is_connected_serial() and self.was_connected:
            self.reset()
            self.device.reset()
            self.start_device()
            self.ctrl_start()
            self.start_objects()
            self.session.reset()
            self.start_session()
        if self.device.get_id() is None:
            # How many devices are connected?
            devices = self.device.detect()
            # If is just one...
            if len(devices) == 1:
                # Configure a new device.
                self.session.reset()
                self.start_device()
                self.ctrl_start()
                self.start_objects()
                self.start_session()
                return False
            # Abort if are more than one.
            if len(devices) > 1 and (len(devices) != self.connected_devices):
                self.connected_devices = len(devices)
                echo.infoln('Too many connected devices: ' + str(devices), 1)
        return False

    def start_device(self):
        """
        description:
        """
        echo.infoln("Device...")
        if not self.device.get_id():
            detected = self.device.detect()
            if len(detected) > 1:
                echo.warnln('Too many connected devices: ' + str(detected), 1)
                return
        echo.debugln(self.device.info())
        if self.device.get_id():
            self.window_title = self.device.system_plat + ' Mark ' + \
                self.device.system_mark
            self.window_caption = self.device.system_plat + ' Mark ' + \
                self.device.system_mark + ' - ' + \
                self.device.system_desc

    def start_screen(self):
        """
        description:
        """
        # global pygame
        echo.infoln("Screen...")
        # Set screen resolution
        self.screen_resolution = [
            int(s) for s in self.screen_size.split('x') if s.isdigit()
        ]
        # Check for minimum resolution
        if (self.screen_resolution[0] < 480) or \
           (self.screen_resolution[1] < 320):
            self.screen_resolution = (480, 320)
        self.screen_resolution[0] -= 1
        self.screen_resolution[1] -= 1
        echo.infoln(
            "Size: " + str(self.screen_resolution[0] + 1) + 'x' +
            str(self.screen_resolution[1] + 1) + ' px', 1)
        echo.infoln("Refresh rate: " + str(self.screen_rate) + ' FPS', 1)
        # Positioning
        os.environ['SDL_VIDEO_CENTERED'] = '1'
        # Initialise screen
        pygame.init()  # pylint: disable=no-member
        self.screen = pygame.display.set_mode(self.screen_resolution)
        if self.screen_full:
            pygame.display.toggle_fullscreen()
        # Window caption
        pygame.display.set_caption(self.window_title)
        # Checking fonts
        echo.debugln('Checking fonts...', 1)
        for ttf_name in ['Digital Readout Thick Upright', 'Ubuntu']:
            ttf_path = pygame.font.match_font(ttf_name)
            if ttf_path is None:
                echo.erroln('TrueType font missing.')
                echo.infoln(
                    '\"' + str(ttf_name) + '\" not found (' + str(ttf_path) +
                    ')', 2)
        # Background
        self.background = pygame.Surface(self.screen.get_size())
        self.background.fill([0, 0, 0])  # Black
        # Controls area
        self.controls = pygame.Surface([120, 240])
        # Object area
        self.object_area = pygame.Surface(
            [self.screen.get_size()[0] - 65,
             self.screen.get_size()[1] - 70])
        # Status bar
        self.status_bar = pygame.Surface([self.screen.get_size()[0], 16])
        # Clockling
        echo.debugln('Clockling...', 1)
        self.clock = pygame.time.Clock()
        # Screensaver
        self.screensaver = Screensaver(self.screen)
        self.screensaver_timer = Timer(1000 * self.screensaver_time,
                                       'COUNTDOWN')
        if not self.screensaver_enable:
            self.screensaver_timer.disable()

    def ctrl_start(self):
        """
        description:
        """
        echo.infoln('Input...')
        self.ctrl_keyboard_start()
        self.ctrl_mouse_start()
        self.ctrl_joystick_start()
        self.ctrl_touch_start()

    def start(self):
        """
        description:
        """
        self.start_host()
        self.start_screen()
        self.start_device()
        self.ctrl_start()
        self.start_objects()
        self.start_session()

    def draw_status(self):
        """
        description:
        """
        # Status bar
        pygame.draw.rect(self.status_bar, (0, 29, 0),
                         (0, 0, self.status_bar.get_size()[0],
                          self.status_bar.get_size()[1]))
        font = pygame.font.SysFont("Digital Readout Thick Upright", 13)
        # Frame rate
        fps = str("FPS: {:1.1f}".format(float(self.clock.get_fps())))
        text = font.render(fps, True, (32, 128, 32))
        textpos = text.get_rect()
        textpos.bottomleft = self.status_bar.get_rect().bottomleft
        textpos[0] += 3
        self.status_bar.blit(text, textpos)
        # Device connection status
        connection = 'Connected' if self.session.is_connected() \
                     else 'Disconnected'
        text = font.render(connection, True, (32, 128, 32))
        textpos = text.get_rect()
        textpos.bottomright = self.status_bar.get_rect().bottomright
        textpos[0] += -3
        self.status_bar.blit(text, textpos)
        # General information
        text = font.render(str(self.host.status()), True, (32, 128, 32))
        textpos = text.get_rect()
        textpos.midbottom = self.status_bar.get_rect().midbottom
        self.status_bar.blit(text, textpos)
        self.screen.blit(self.status_bar, [0, self.screen.get_size()[1] - 16])