Exemplo n.º 1
0
class SimpleClock(ClockFace):
    def __init__(self, config, *args, **kwargs):
        super().__init__(config, *args, **kwargs)
        self.logger = logging.getLogger(__class__.__name__)

        self.clock_y = 0
        self.clock_height = 7
        self.direction = 1

        self.timer = SafeTimer(self.on_timer,
                               max(0.1, self.config.get('interval', 0)))

        self.font = [[0]] * (ord(':') + 1)

        for ch in range(ord('0'), ord('9') + 1):
            self.font[ch] = BIG_DIGITS[ch]

        self.font[ord('\t')] = [0x00, 0x00, 0x00, 0x00, 0x00]
        self.font[ord(':')] = [0x00, 0x22, 0x00, 0x00, 0x00]

    def enter(self):
        self.timer.start(True)

    def exit(self):
        self.timer.stop()

    def on_timer(self):
        now = datetime.datetime.now()

        if now.microsecond > 500000:
            time_string = now.strftime("%H:%M")
        else:
            time_string = now.strftime("%H\t%M")

        x = (self.width - textsize(time_string, self.font)[0] + 1) / 2

        image = Image.new('1', (self.width, self.height))
        canvas = ImageDraw.Draw(image)
        text(canvas, (x, self.clock_y), time_string, 255, self.font)
        del canvas
        self.manager.draw_activity(self, image)

        self.clock_y += self.direction

        if self.clock_y == 0 or self.clock_y + self.clock_height == self.height:
            self.direction = -self.direction
Exemplo n.º 2
0
class TetrisApp(ClockApp):
    def __init__(self, config, *args, **kwargs):
        super().__init__(config, *args, **kwargs)
        self.logger = logging.getLogger(__class__.__name__)

        self.timer = SafeTimer(self.on_timer,
                               max(0.1, self.config.get('interval', 0)))

        self.x = self.width / 2
        self.y = self.height / 2

    def enter(self):
        self.timer.start(True)

    def exit(self):
        self.timer.stop()

    def on_timer(self):
        image = Image.new('1', (self.width, self.height))
        canvas = ImageDraw.Draw(image)
        canvas.point((self.x, self.y), 255)
        del canvas
        self.manager.draw_activity(self, image)

    def input(self, btn):
        if btn == InputButtons.BTN_LEFT:
            self.x -= 1

        if btn == InputButtons.BTN_RIGHT:
            self.x += 1

        if btn == InputButtons.BTN_UP:
            self.y -= 1

        if btn == InputButtons.BTN_DOWN:
            self.y += 1

        if self.x < 0:
            self.x = self.width - 1
        if self.x >= self.width:
            self.x = 0

        if self.y < 0:
            self.y = self.height - 1
        if self.y >= self.height:
            self.y = 0
Exemplo n.º 3
0
class Emulator(ClockService):
    def __init__(self, config, *args, **kwargs):
        super().__init__(config, *args, **kwargs)
        self.logger = logging.getLogger(__class__.__name__)

        self.upper_temp = self.config['upper_temp']
        self.lower_temp = self.config['lower_temp']
        self.upper_hum = self.config['upper_hum']
        self.lower_hum = self.config['lower_hum']
        self.upper_press = self.config['upper_press']
        self.lower_press = self.config['lower_press']

        self.timer = SafeTimer(self.on_timer,
                               max(1, self.config.get('interval', 0)))

    def start(self):
        self.logger.info("Starting")
        self.timer.start(True)
        self.logger.info("Started")

    def stop(self):
        self.logger.info("Stopping")
        self.timer.stop()
        self.logger.info("Stopped")

    def on_timer(self):
        temperature = random.randint(self.lower_temp, self.upper_temp)
        humidity = random.randint(self.lower_hum, self.upper_hum)
        pressure = random.randint(self.lower_press, self.upper_press)

        self.logger.debug(
            "Temperature: {0},  Humidity: {1}, Pressure: {2}".format(
                temperature, humidity, pressure))

        self.manager.set_info(self, 'temperature', temperature)
        self.manager.set_info(self, 'humidity', humidity)
        self.manager.set_info(self, 'pressure', pressure)
Exemplo n.º 4
0
class Weather(ClockFace):
    def __init__(self, config, *args, **kwargs):
        super().__init__(config, *args, **kwargs)
        self.logger = logging.getLogger(__class__.__name__)

        self.timer = SafeTimer(self.on_timer,
                               max(1, self.config.get('interval', 0)))

        self.font = [x for x in ProportionalFont(MICRO_LETTERS, 2)]
        self.font[ord('\t')] = [0x00]

        self.time = MiniClock(0, 0)

        self.time.x = (self.width - self.time.width) // 2

    def enter(self):
        self.timer.start(True)

    def exit(self):
        self.timer.stop()

    def on_timer(self):
        temperature = self.manager.get_info(self, 'temperature')
        humidity = self.manager.get_info(self, 'humidity')
        pressure = self.manager.get_info(self, 'pressure')

        image = Image.new('1', (self.width, self.height))
        canvas = ImageDraw.Draw(image)

        self.time.draw(canvas)

        text(canvas, (0, 7), "T: %d" % int(temperature), 255, self.font)
        text(canvas, (0, 13), "H: %d" % int(humidity), 255, self.font)
        text(canvas, (0, 19), "P: %d" % int(pressure), 255, self.font)

        del canvas
        self.manager.draw_activity(self, image)
Exemplo n.º 5
0
class WeatherPredictor(ClockService):
    def __init__(self, config, *args, **kwargs):
        super().__init__(config, *args, **kwargs)
        self.logger = logging.getLogger(__class__.__name__)

        self.timer = SafeTimer(self.on_timer,
                               max(600, self.config.get('interval', 0)))
        self.approxSize = self.config.get('approx_size', 6)
        self.historySize = self.config.get('history_size', 144)

        self.deltaMin = self.config.get('delta_min', 250)
        self.deltaMax = self.config.get('delta_max', -250)

    def start(self):
        self.logger.info("Starting")
        self.timer.start(True)
        self.logger.info("Started")

    def stop(self):
        self.logger.info("Stopping")
        self.timer.stop()
        self.logger.info("Stopped")

    def get_rain_probability(self, pressure_points):
        sum_x = 0.0
        sum_y = 0.0
        sum_x2 = 0.0
        sum_xy = 0.0

        approx_size = len(pressure_points)

        for i in range(approx_size):
            sum_x += i
            sum_y += pressure_points[i]
            sum_x2 += i * i
            sum_xy += i * pressure_points[i]

        a = (approx_size * sum_xy - sum_x * sum_y) / (
            approx_size * sum_x2 - sum_x * sum_x) * approx_size
        rain = (a - self.deltaMin) * 2 / (self.deltaMax - self.deltaMin) - 1

        if rain < -1.0:
            rain = -1.0
        elif rain > 1.0:
            rain = 1.0

        return rain

    def on_timer(self):
        pressure = self.manager.get_info(self, 'pressure')

        pressure_history = self.manager.get_info(self, 'pressure_history')
        if not pressure_history:
            pressure_history = []

        pressure_history.append(pressure)

        while len(pressure_history) > self.historySize:
            pressure_history = pressure_history[1:]

        self.manager.set_info(self, 'pressure_history', pressure_history, True)

        approx_points = pressure_history[-self.approxSize:]

        while len(approx_points) < self.approxSize:
            approx_points.insert(0, approx_points[0])

        rain_probability = self.get_rain_probability(approx_points)

        self.manager.set_info(self, 'rain_probability', rain_probability)
Exemplo n.º 6
0
class Physical(ClockService):
    def __init__(self, config, *args, **kwargs):
        super().__init__(config, *args, **kwargs)
        self.logger = logging.getLogger(__class__.__name__)

        self.busNumber = config.get('smbus', 0)
        self.timer = SafeTimer(self.on_timer, max(1, self.config.get('interval', 0)))
        self.measureCycles = config.get('measure_cycles', 10)
        self.measureDelay = config.get('measure_delay', 0.01)

        self.smbus = None
    def start(self):

        self.si7021 = None
        self.bme208 = None

    def start(self):
        self.logger.info("Starting")
        self.smbus = SMBus(self.busNumber)
        self.si7021 = Si7021(self.smbus)
        self.si7021.reset()

        self.bme208 = Bme280(self.smbus)
        self.bme208.setup()

        self.timer.start(True)
        self.logger.info("Started")

    def stop(self):
        self.logger.info("Stopping")
        self.timer.stop()
        self.smbus.close()
        self.smbus = None
        self.logger.info("Stopped")

    def measure(self):
        hum1, temp1 = self.si7021.read()
        hum2, temp2, pres2 = self.bme208.read()

        temperature = (temp1 + temp2) / 2
        pressure = pres2
        humidity = hum1

        return temperature, pressure, humidity

    def on_timer(self):
        t, p, h = self.measure()
        temperature = t
        pressure = p
        humidity = h


        for n in range(1,self.measureCycles):
            time.sleep(self.measureDelay)
            t, p, h = self.measure()
            temperature += t
            pressure += p
            humidity += h

        temperature /= self.measureCycles
        pressure /= self.measureCycles
        humidity /= self.measureCycles

        self.logger.debug("Temperature: {0},  Humidity: {1}, Pressure: {2}".format(temperature, humidity, pressure))
        self.manager.set_info(self, 'temperature', temperature)
        self.manager.set_info(self, 'humidity', humidity)
        self.manager.set_info(self, 'pressure', pressure)
Exemplo n.º 7
0
class ClockCore:
    def __init__(self, config, services_config, faces_config, apps_config):
        self.logger = logging.getLogger(__class__.__name__)
        self.config = config

        transition_interval = self.config['transition']['interval']
        self.transition_step = self.config['transition']['step']

        self.transition_timer = SafeTimer(self.on_transition_timer,
                                          transition_interval, 'transition')

        self.screen = ClockScreen(self.config['screen'])
        self.input = ClockInput(self.config['input'])
        self.storage = ClockStorage(self.config['storage'])

        self.input.on_input += self.on_input

        self.services = []
        self.faces = []
        self.apps = []

        self.current_activity = None

        self.primary_image = None
        self.secondary_image = None

        self.transition_direction = None
        self.primary_x = 0
        self.primary_y = 0

        self.logger.info("Loading services")
        self.services = self.load_plugins(
            services_config, "services",
            lambda create, name, conf: create(conf, self))
        self.logger.info("Loading faces")
        self.faces = self.load_plugins(
            faces_config, "faces", lambda create, name, conf: create(
                conf, self, self.screen.width, self.screen.height))
        self.logger.info("Loading apps")
        self.apps = self.load_plugins(
            apps_config, "apps", lambda create, name, conf: create(
                conf, self, self.screen.width, self.screen.height))

        self.current_face_index = 0

    def get_info(self, activity, key):
        return self.storage.get_info(activity, key)

    def set_info(self, activity, key, value, store=False):
        self.storage.set_info(activity, key, value, store)

    def draw_activity(self, activity, image):
        if activity != self.current_activity:
            return

        self.primary_image = image

        if self.transition_direction is None:
            self.screen.display_image(image)

    def load_plugins(self, plugins, plugin_folder, factory):
        result = []
        for (name, config) in plugins.items():
            if not config.get("enabled", True):
                continue

            self.logger.debug("Loading {0}".format(name))
            module = importlib.import_module("%s.%s" % (plugin_folder, name))
            result.append(factory(module.create, name, config))

        return result

    def on_input(self, btn):
        self.logger.debug("Got input: %s" % btn)

        if btn == InputButtons.BTN_SHARP:
            self.restart_screen()

        if self.current_activity.receives_input():
            if not self.current_activity.overrides_exit(
            ) and btn == InputButtons.BTN_STAR:
                self.close_app(self.current_activity)
            else:
                self.current_activity.input(btn)
            return

        app = None

        try:
            app_index = InputUtils.NumericButtonsSequence.index(btn)
            app = self.apps[app_index]

        except IndexError:
            pass
        except ValueError:
            pass

        if app is not None:
            self.open_app(app)
            return

        transition_direction = None

        if btn == InputButtons.BTN_LEFT:
            self.current_face_index -= 1
            if self.current_face_index < 0:
                self.current_face_index = len(self.faces) - 1
            transition_direction = TransitionDirections.RIGHT

        if btn == InputButtons.BTN_RIGHT:
            self.current_face_index += 1
            if self.current_face_index >= len(self.faces):
                self.current_face_index = 0
            transition_direction = TransitionDirections.LEFT

        if btn == InputButtons.BTN_UP:
            self.current_face_index -= 1
            if self.current_face_index < 0:
                self.current_face_index = len(self.faces) - 1
            transition_direction = TransitionDirections.DOWN

        if btn == InputButtons.BTN_DOWN:
            self.current_face_index += 1
            if self.current_face_index >= len(self.faces):
                self.current_face_index = 0
            transition_direction = TransitionDirections.UP

        self.change_activity(self.faces[self.current_face_index],
                             transition_direction)

    def restart_screen(self):
        self.logger.info("Restarting screen")
        activity = self.current_activity
        self.current_activity.exit()
        self.current_activity = None

        self.transition_direction = None
        self.transition_timer.stop()

        self.screen.stop()
        self.screen.start()

        self.current_activity = activity
        self.current_activity.enter()

    def start(self):
        self.logger.info("Starting")

        self.screen.start()
        self.input.start()
        self.storage.start()

        for plugin in self.services:
            plugin.start()
        for plugin in self.faces:
            plugin.start()
        for plugin in self.apps:
            plugin.start()

        self.current_activity = self.faces[self.current_face_index]
        self.current_activity.enter()

        self.logger.info("Started")

    def stop(self):
        self.logger.info("Stopping")
        self.current_activity.exit()

        for plugin in self.apps:
            plugin.stop()
        for plugin in self.faces:
            plugin.stop()
        for plugin in self.services:
            plugin.stop()

        self.storage.stop()
        self.input.stop()
        self.screen.stop()
        self.logger.info("Stopped")

    def open_app(self, app):
        self.change_activity(app, TransitionDirections.LEFT)

    def close_app(self, app):
        if app != self.current_activity:
            return

        self.change_activity(self.faces[self.current_face_index],
                             TransitionDirections.RIGHT)

    def change_activity(self, activity, transition_direction):
        self.current_activity.exit()
        self.transition_direction = transition_direction
        current_image = self.primary_image

        self.current_activity = activity
        self.current_activity.enter()

        if transition_direction is None:
            return

        self.secondary_image = current_image

        self.primary_x = 0
        self.primary_y = 0

        if transition_direction == TransitionDirections.UP:
            self.primary_y = self.screen.height
        if transition_direction == TransitionDirections.DOWN:
            self.primary_y = -self.screen.height
        if transition_direction == TransitionDirections.LEFT:
            self.primary_x = self.screen.width
        if transition_direction == TransitionDirections.RIGHT:
            self.primary_x = -self.screen.width

        self.transition_timer.start()

    def on_transition_timer(self):
        if self.transition_direction is None:
            return

        if self.transition_direction == TransitionDirections.UP:
            self.primary_y -= self.transition_step
            if self.primary_y < 0:
                self.primary_y = 0
        if self.transition_direction == TransitionDirections.DOWN:
            self.primary_y += self.transition_step
            if self.primary_y > 0:
                self.primary_y = 0
        if self.transition_direction == TransitionDirections.LEFT:
            self.primary_x -= self.transition_step
            if self.primary_x < 0:
                self.primary_x = 0
        if self.transition_direction == TransitionDirections.RIGHT:
            self.primary_x += self.transition_step
            if self.primary_x > 0:
                self.primary_x = 0

        image = Image.new('1', (self.screen.width, self.screen.height))

        secondary_x = self.primary_x
        secondary_y = self.primary_y

        if secondary_x > 0:
            secondary_x -= self.screen.width
        elif secondary_x < 0:
            secondary_x += self.screen.width

        if secondary_y > 0:
            secondary_y -= self.screen.height
        elif secondary_y < 0:
            secondary_y += self.screen.height

        image.paste(self.secondary_image, (secondary_x, secondary_y))
        image.paste(self.primary_image, (self.primary_x, self.primary_y))

        self.screen.display_image(image)

        if self.primary_x == 0 and self.primary_y == 0:
            self.transition_timer.stop()
            self.secondary_image = None
            self.transition_direction = None
Exemplo n.º 8
0
class AnalogClock(ClockFace):
    def __init__(self, config, *args, **kwargs):
        super().__init__(config, *args, **kwargs)
        self.logger = logging.getLogger(__class__.__name__)

        self.timer = SafeTimer(self.on_timer,
                               max(0.1, self.config.get('interval', 0)))
        self.font = proportional(LCD_FONT)

        self.size = min(self.width, self.height)

        if self.size % 2 == 0:
            self.size -= 1

        self.second_len = config.get('second_len', self.size / 2 - 2)
        self.minute_len = config.get('minute_len', self.size / 2 - 3)
        self.hour_len = config.get('hour_len', self.size / 2 - 5)

        self.background = None

    def start(self):

        self.background = Image.new('1', (self.size, self.size))

        canvas = ImageDraw.Draw(self.background)

        center = int(self.size / 2)

        for h in range(0, 12):
            x = center + int(math.sin(h * math.pi / 6) * self.size / 2)
            y = center - int(math.cos(h * math.pi / 6) * self.size / 2)
            canvas.point((x, y), 255)

        canvas.point((self.size / 2, 1), 255)
        canvas.point((self.size / 2, self.size - 2), 255)
        canvas.point((1, self.size / 2), 255)
        canvas.point((self.size - 2, self.size / 2), 255)

        del canvas

    def stop(self):
        self.background.close()
        self.background = None

    def enter(self):
        self.timer.start(True)

    def exit(self):
        self.timer.stop()

    def on_timer(self):
        now = datetime.datetime.now()

        seconds = now.second
        minutes = now.minute + seconds / 60.0
        hours = now.hour + minutes / 60.0

        if hours > 12:
            hours -= 12

        image = Image.new('1', (self.width, self.height))

        bg_x = int((self.width - self.background.width) / 2)
        bg_y = int((self.height - self.background.height) / 2)

        image.paste(self.background, (bg_x, bg_y))

        center_x = int(bg_x + self.background.width / 2)
        center_y = int(bg_y + self.background.height / 2)

        canvas = ImageDraw.Draw(image)

        arrow_len = self.background.width / 2

        hour_x = center_x + int(math.sin(hours * math.pi / 6) * self.hour_len)
        hour_y = center_y - int(math.cos(hours * math.pi / 6) * self.hour_len)

        minute_x = center_x + int(
            math.sin(minutes * math.pi / 30) * self.minute_len)
        minute_y = center_y - int(
            math.cos(minutes * math.pi / 30) * self.minute_len)

        second_x = center_x + int(
            math.sin(seconds * math.pi / 30) * self.second_len)
        second_y = center_y - int(
            math.cos(seconds * math.pi / 30) * self.second_len)

        canvas.line([center_x, center_y, hour_x, hour_y], 255)
        canvas.line([center_x, center_y, minute_x, minute_y], 255)

        if image.getpixel((second_x, second_y)):
            canvas.point([second_x, second_y], 0)
        else:
            canvas.point([second_x, second_y], 255)

        canvas.ellipse(
            [center_x - 1, center_y - 1, center_x + 1, center_y + 1], 0)
        canvas.point([center_x, center_y], 255)
        del canvas
        self.manager.draw_activity(self, image)
Exemplo n.º 9
0
class SnakeApp(ClockApp):
    def __init__(self, config, *args, **kwargs):
        super().__init__(config, *args, **kwargs)
        self.logger = logging.getLogger(__class__.__name__)

        self.minInterval = self.config.get('min_interval', 0.1)
        self.maxInterval = self.config.get('max_interval', 1.0)

        self.intervalStep = (self.maxInterval - self.minInterval) / 9
        self.level = 5

        self.timer = SafeTimer(self.on_timer, self.maxInterval - self.intervalStep * self.level)

        self.snake = None
        self.dx = 0
        self.dy = 0
        self.apple = None
        self.score = 0
        self.gameOver = False

        self.btn = None

        self.gameWidth = self.width
        self.gameHeight = self.height - 6

        self.main_font = [x for x in ProportionalFont(MICRO_LETTERS, 2)]
        self.main_font[ord('\t')] = [0x00]

        self.clock = MiniClock(0, 0)
        self.clock.x = self.width - self.clock.width

    def start(self):
        self.init_game()

    def gen_apple_pos(self):
        while True:
            x, y = random.randrange(self.gameWidth), random.randrange(self.gameHeight)
            if (x, y) not in self.snake:
                return x, y

    def init_game(self):
        self.snake = [
            (int(self.gameWidth / 2) - 1, int(self.gameHeight / 2)),
            (int(self.gameWidth / 2), int(self.gameHeight / 2)),
            (int(self.gameWidth / 2) + 1, int(self.gameHeight / 2))
        ]

        self.score = 0

        self.dx = 1
        self.dy = 0
        self.apple = self.gen_apple_pos()

        self.gameOver = False
        self.btn = None

    def get_next_pos(self):
        x, y = self.snake[-1]
        x += self.dx
        y += self.dy

        if x >= self.gameWidth:
            x = 0
        if x < 0:
            x = self.gameWidth - 1
        if y >= self.gameHeight:
            y = 0
        if y < 0:
            y = self.gameHeight - 1

        return x, y

    def enter(self):
        self.timer.start(True)

    def exit(self):
        self.timer.stop()

    def draw(self):
        image = Image.new('1', (self.width, self.height))
        canvas = ImageDraw.Draw(image)

        self.clock.draw(canvas)

        text(canvas, (0, 0), str(self.score), 255, self.main_font)

        canvas.point((self.apple[0], self.apple[1] + 6), 255)
        for x, y in self.snake:
            canvas.point((x, y + 6), 255)

        if self.gameOver:
            canvas.rectangle((0, 13, self.width, 19), 0, 0)
            text(canvas, (0, 14), "GAME\tOVER", 255, self.main_font)

        del canvas
        self.manager.draw_activity(self, image)

    def on_timer(self):
        if self.gameOver:
            self.draw()
            return

        if self.btn == InputButtons.BTN_UP and self.dx != 0:
            self.dx = 0
            self.dy = -1
        if self.btn == InputButtons.BTN_DOWN and self.dx != 0:
            self.dx = 0
            self.dy = 1
        if self.btn == InputButtons.BTN_LEFT and self.dy != 0:
            self.dx = -1
            self.dy = 0
        if self.btn == InputButtons.BTN_RIGHT and self.dy != 0:
            self.dx = 1
            self.dy = 0

        next_pos = self.get_next_pos()

        if next_pos in self.snake:
            self.gameOver = True
        else:
            self.snake.append(next_pos)

            if next_pos != self.apple:
                self.snake = self.snake[1:]
            else:
                self.score += self.level + 1
                self.apple = self.gen_apple_pos()

        self.draw()

    def input(self, btn):
        if btn == InputButtons.BTN_OK:
            self.init_game()
            return

        if btn == InputButtons.BTN_0:
            return

        index = InputUtils.get_numeric_button_index(btn)

        if index is not None:
            self.level = index
            self.timer.interval = self.maxInterval - self.intervalStep * self.level
            return

        self.btn = btn
Exemplo n.º 10
0
class LifeApp(ClockApp):
    def __init__(self, config, *args, **kwargs):
        super().__init__(config, *args, **kwargs)
        self.logger = logging.getLogger(__class__.__name__)

        self.minInterval = self.config.get('min_interval', 0.1)
        self.maxInterval = self.config.get('max_interval', 1.0)
        self.intervalStep = self.config.get('interval_step', 0.1)

        self.intervalBarDelay = self.config.get('interval_bar_delay', 1.0)

        self.interval = self.config.get('interval', 0.3)

        self.interval = min(self.interval, self.maxInterval)
        self.interval = max(self.interval, self.minInterval)

        self.lastIntervalChange = None

        self.timer = SafeTimer(self.on_timer, self.interval)

        self.cells = None
        self.new_cells = None

        self.intervalBar = ProgressBar(ProgressBar.HORIZONTAL,
                                       -self.maxInterval, -self.minInterval,
                                       -self.interval, 4,
                                       (self.height - 8) / 2, self.width - 8,
                                       8)

    def start(self):
        self.init_cells()

    def init_cells(self):
        self.cells = [[random.choice([0, 255]) for x in range(self.height)]
                      for y in range(self.width)]
        self.new_cells = [[0 for x in range(self.height)]
                          for y in range(self.width)]

    def enter(self):
        self.timer.start(True)

    def exit(self):
        self.timer.stop()

    def near(self, x, y, system=None):
        if system is None:
            system = [[-1, -1], [-1, 0], [-1, 1], [0, -1], [0, 1], [1, -1],
                      [1, 0], [1, 1]]
        count = 0
        for i in system:
            if self.cells[(x + i[0]) % self.width][(y + i[1]) % self.height]:
                count += 1
        return count

    def draw(self):
        image = Image.new('1', (self.width, self.height))
        canvas = ImageDraw.Draw(image)

        for x in range(self.width):
            for y in range(self.height):
                canvas.point((x, y), self.cells[x][y])

        if (self.lastIntervalChange is not None
                and (datetime.datetime.now() - self.lastIntervalChange
                     ).total_seconds() <= self.intervalBarDelay):
            self.intervalBar.draw(canvas)

        del canvas
        self.manager.draw_activity(self, image)

    def on_timer(self):
        anybody_alive = False

        self.draw()

        for x in range(self.width):
            for y in range(self.height):
                if self.cells[x][y]:
                    if self.near(x, y) not in (2, 3):
                        self.new_cells[x][y] = 0
                    else:
                        self.new_cells[x][y] = 255
                        anybody_alive = True
                elif self.near(x, y) == 3:
                    self.new_cells[x][y] = 255
                    anybody_alive = True
                else:
                    self.new_cells[x][y] = 0

        tmp = self.cells
        self.cells = self.new_cells
        self.new_cells = tmp

        if not anybody_alive:
            self.init_cells()

    def input(self, btn):
        if btn == InputButtons.BTN_OK:
            self.init_cells()

        interval_changed = False

        if btn == InputButtons.BTN_UP or btn == InputButtons.BTN_RIGHT:
            self.interval -= self.intervalStep
            interval_changed = True

        if btn == InputButtons.BTN_DOWN or btn == InputButtons.BTN_LEFT:
            self.interval += self.intervalStep
            interval_changed = True

        if interval_changed:
            self.interval = min(self.interval, self.maxInterval)
            self.interval = max(self.interval, self.minInterval)

            self.timer.interval = self.interval
            self.intervalBar.value = -self.interval

            self.lastIntervalChange = datetime.datetime.now()
            self.draw()
Exemplo n.º 11
0
class FlameTestApp(ClockApp):
    def __init__(self, config, *args, **kwargs):
        super().__init__(config, *args, **kwargs)
        self.logger = logging.getLogger(__class__.__name__)

        self.timer = SafeTimer(self.on_timer,
                               max(0.05, self.config.get('interval', 0)))

        self.minHotspots = self.config.get('min_hotspots', 2)
        self.maxHotspots = self.config.get('max_hotspots', 16)
        self.hotspotStep = self.config.get('hotspot_step', 2)
        self.hotspots = self.config.get('hotspots', 6)

        self.minValue = self.config.get('min_value', 20)
        self.maxValue = self.config.get('max_value', 200)
        self.valueStep = self.config.get('value_step', 2)
        self.value = self.config.get('value', 40)

        self.barDelay = self.config.get('bar_delay', 1.0)

        self.main_frame = [[0 for x in range(self.height + 2)]
                           for y in range(self.width + 2)]
        self.back_frame = [[0 for x in range(self.height + 2)]
                           for y in range(self.width + 2)]

        self.hotspotBar = ProgressBar(ProgressBar.HORIZONTAL, self.minHotspots,
                                      self.maxHotspots, self.hotspots, 4,
                                      (self.height - 8) / 2, self.width - 8, 8)
        self.valueBar = ProgressBar(ProgressBar.VERTICAL, self.minValue,
                                    self.maxValue, self.value,
                                    (self.width - 8) / 2, 2, 8,
                                    self.height - 4)

        self.visibleBar = None
        self.visibleBarTimestamp = None

    def place_spots(self):
        for n in range(self.hotspots):
            x = random.randrange(1, self.width + 1)
            self.main_frame[x][self.height] = self.value

    def move_frame(self):
        for x in range(1, self.width + 1):
            for y in range(1, self.height + 1):
                self.back_frame[x][y - 1] = (
                    self.main_frame[x - 1][y - 1] + self.main_frame[x - 1][y] +
                    self.main_frame[x - 1][y + 1] + self.main_frame[x][y - 1] +
                    self.main_frame[x][y] + self.main_frame[x][y + 1] +
                    self.main_frame[x + 1][y - 1] + self.main_frame[x + 1][y] +
                    self.main_frame[x + 1][y + 1]) // 9

        for x in range(1, self.width + 1):
            self.back_frame[x][self.height] = 0

        tmp = self.main_frame
        self.main_frame = self.back_frame
        self.back_frame = tmp

    def enter(self):
        self.timer.start(True)

    def exit(self):
        self.timer.stop()

    def draw(self):
        image = Image.new('1', (self.width, self.height))
        canvas = ImageDraw.Draw(image)

        for x in range(self.width):
            for y in range(self.height):
                canvas.point((x, y),
                             255 if self.main_frame[x + 1][y] > 0 else 0)

        if (self.visibleBar is not None
                and self.visibleBarTimestamp is not None and
            (datetime.datetime.now() -
             self.visibleBarTimestamp).total_seconds() <= self.barDelay):
            self.visibleBar.draw(canvas)

        del canvas
        self.manager.draw_activity(self, image)

    def on_timer(self):
        self.place_spots()
        self.move_frame()
        self.draw()

    def input(self, btn):
        now = datetime.datetime.now()

        if btn == InputButtons.BTN_RIGHT:
            self.hotspots += self.hotspotStep
            self.visibleBar = self.hotspotBar
            self.visibleBarTimestamp = now

        if btn == InputButtons.BTN_LEFT:
            self.hotspots -= self.hotspotStep
            self.visibleBar = self.hotspotBar
            self.visibleBarTimestamp = now

        if btn == InputButtons.BTN_UP:
            self.value += self.valueStep
            self.visibleBar = self.valueBar
            self.visibleBarTimestamp = now

        if btn == InputButtons.BTN_DOWN:
            self.value -= self.valueStep
            self.visibleBar = self.valueBar
            self.visibleBarTimestamp = now

        self.value = min(self.value, self.maxValue)
        self.value = max(self.value, self.minValue)

        self.hotspots = min(self.hotspots, self.maxHotspots)
        self.hotspots = max(self.hotspots, self.minHotspots)

        self.valueBar.value = self.value
        self.hotspotBar.value = self.hotspots