Exemple #1
0
def IntermezzoInvaders(previous_frame: Frame, next_frame: Frame):
    """
    Show Invaders from the top to the bottom switching programs.
    """
    config = Config()
    prv = previous_frame.raw()
    nxt = next_frame.raw()
    seq = FrameSequence()
    frame_delay = config['INVADERS_FRAME_DELAY']
    height = config['DISPLAY_HEIGHT']
    width = config['DISPLAY_WIDTH']
    size = height * width
    invader_height = int(len(_invaders(0)) / width)
    for step in range(height + invader_height +
                      4):  # lets go from top to bottom
        img = bytearray().join([
            nxt,
            bytearray(width),  # Empty.
            bytearray(width),  # Empty.
            _invaders(step),
            bytearray(width),  # Empty.
            bytearray(width),  # Empty.
            prv
        ])
        if step == 0:
            frame_data = img[-1 * size - (step * width):]
        else:
            frame_data = img[-1 * size - (step * width):-(step * width)]
        seq.add_frame(Frame(frame_data, frame_delay))
    return seq
Exemple #2
0
def AnimateVerticalScroll(image: bytearray, line_duration: int) -> list:
    """
    I let the content of a longer image scroll vertically up.
    :param image: The image that there is to scroll.
    :type image: bytearray
    :param line_duration: The duration in ms that each line should be shown.
    :type line_duration: int
    :return: List of frames that make up the scrolling motion.
    :rtype: list
    """
    config = Config()
    display_width = config['DISPLAY_WIDTH']
    animate_duration = config['TYPESETTER_ANIMATE_VERTICAL_SCROLL_DELAY']
    nr_of_lines = len(image) / display_width  # nr of lines does the whole image has.
    nr_of_scroll = int(nr_of_lines - config['DISPLAY_HEIGHT'])  # number of lines there are to scroll
    f_start = 0
    f_end = config['DISPLAY_SIZE']
    frames = []
    for nr in range(nr_of_scroll):
        if nr % 8 == 0:  # On a full line, show for longer.
            duration = line_duration
        else:
            duration = animate_duration
        frames.append(Frame(image[f_start:f_end], duration=duration))
        f_start += display_width
        f_end += display_width
    frames.append(Frame(image[-config['DISPLAY_SIZE']:], duration=line_duration))
    return frames
Exemple #3
0
 def test_pacman(self):
     config = Config()
     image_size = config.get('DISPLAY_SIZE')
     prev_frame = Frame(bytearray(b'0' * image_size), 1)
     next_frame = Frame(bytearray(b'1' * image_size), 1)
     seq = IntermezzoPacman(prev_frame, next_frame)
     verify_length(seq, image_size)
Exemple #4
0
 def test_fram_length(self):
     config = Config()
     image_size = config.get('DISPLAY_SIZE')
     prev_frame = Frame(bytearray([0x66]*image_size), 100)
     next_frame = Frame(bytearray([0x66]*image_size), 100)
     seq = IntermezzoInvaders(prev_frame, next_frame)
     verify_length(seq, image_size)
Exemple #5
0
 def test_intermezzo_wipe(self):
     catalog = Catalog()
     catalog.add_intermezzo(IntermezzoWipe)
     self._create_and_add_sequence(catalog, 'second',
                                   [Frame(bytearray(b'\x00' * 3456), 10)])
     self._create_and_add_sequence(catalog, 'first',
                                   [Frame(bytearray(b'\xff' * 3456), 10)])
     f_iter = catalog.frames_iter()
     res = next(f_iter)
     assert 0xff == res.raw()[0]
     res2 = next(f_iter)
     assert 0x0 == res2.raw()[0]
Exemple #6
0
    def test_AnimateStill(self, sched):
        seq = FrameSequence()
        img_data = bytearray(Config().get('DISPLAY_SIZE'))
        seq.add_frame(Frame(img_data, 2000))
        animated_seq = AnimateStill(seq[0])
        assert Config().get('DISPLAY_HEIGHT') == len(animated_seq)
        assert sum([frame.duration for frame in animated_seq.frames]) == 2000

        seq.add_frame(Frame(img_data, None))
        animated_seq = AnimateStill(seq[1])
        assert Config()['DISPLAY_DEFAULT_DELAY'] == sum(
            [frame.duration for frame in animated_seq.frames])
Exemple #7
0
 def test_mark_program_progress(self):
     catalog = Catalog()
     seq = self._create_and_add_sequence(
         catalog, 'first', [Frame(bytearray(b'\xff' * 3456), 10)])
     gen = catalog.mark_program_progress(seq, 0, 5)
     next(gen)
     gen = catalog.mark_program_progress(seq, 4, 5)
     next(gen)
Exemple #8
0
 def typeset_alert(self, topic: str, msg: TextAlertLayout) -> FrameSequence:
     assert topic.split('/')[-1] == "spacealert"
     text = msg.text
     who = msg.who
     fs = FrameSequence()
     char_width = self._char_display_width()
     fs.program = msg.program
     alert = self.typeset_1line("Space Alert!", 20)
     alert_neg = bytearray([(~x & 0xff) for x in alert])
     fs.add_frame(Frame(alert, duration=200))
     fs.add_frame(Frame(alert_neg, duration=200))
     fs.add_frame(Frame(alert, duration=200))
     fs.add_frame(Frame(alert_neg, duration=200))
     if text:
         three_line_msg = TextTripleLinesLayout()
         three_line_msg.lines = ["From %s" % who, text[:char_width], text[char_width:]]
         three_line_msg.duration = 2000
         self.typeset_3lines(fs, three_line_msg)
     fs.prio = "alert"
     return fs
Exemple #9
0
def IntermezzoWipe(previous_frame: Frame, next_frame: Frame):
    config = Config()
    wipe_frame_delay = config['INTERMEZZO_WIPE_FRAME_DELAY']
    wipe_frame_step_size = config['INTERMEZZO_WIPE_FRAME_STEP_SIZE']
    prv = previous_frame.raw()
    nxt = next_frame.raw()
    seq = FrameSequence()
    height = config['DISPLAY_HEIGHT']
    width = config['DISPLAY_WIDTH']
    sep = bytearray([0x00, 0x00, 0x40, 0x60, 0x80, 0x80, 0xff, 0x00])
    sep_len = len(sep)
    for step in range(wipe_frame_step_size,
                      width - wipe_frame_step_size - sep_len,
                      wipe_frame_step_size):
        img_data = bytearray()
        for row in range(0, height):
            start = width * row
            img_data.extend(nxt[start:start + step] + sep +
                            prv[start + step + sep_len:start + width])
        seq.add_frame(Frame(img_data, wipe_frame_delay))
    return seq
Exemple #10
0
def gif():
    f = request.files['f']
    program = request.form['program']
    try:
        im = Image.open(f)
    except OSError:
        raise UnsupportedMediaType()
    sequence = FrameSequence()
    for frame_raw in ImageSequence.Iterator(im):
        image_data, duration = process_frame(frame_raw)
        sequence.add_frame(Frame(image_data, duration))
    payload = send_image(sequence, program)
    return Response(payload, mimetype='application/json')
Exemple #11
0
def AnimateStill(still: Frame):
    """
    I take a frame and create a sequence where the duration of the frame is visible.
    :param still: The image to animate.
    :type still: Frame
    :return: The sequence of frames with the time animation.
    :rtype: FrameSequence
    """
    seq = FrameSequence()
    width, height = Config().get('DISPLAY_WIDTH'), Config().get('DISPLAY_HEIGHT')
    seq_duration = still.duration
    if not seq_duration:
        seq_duration = Config()['DISPLAY_DEFAULT_DELAY']
    steps_ms = int(seq_duration / height)
    still_img = still.raw()
    still.duration = steps_ms
    for nr in range(height):
        frame = bytearray(still_img)
        frame[width*nr-1] = 0xff
        seq.add_frame(Frame(frame, steps_ms))
    seq[-1].duration += seq_duration - seq.duration  # Add the steps_ms missing because of the division.
    return seq
Exemple #12
0
def IntermezzoPacman(previous_frame: Frame, next_frame: Frame):
    config = Config()
    frame_move = config['PACMAN_MOVE']
    frame_delay = config['PACMAN_DELAY']
    prv = previous_frame.raw()
    nxt = next_frame.raw()
    seq = FrameSequence()
    height = config['DISPLAY_HEIGHT']
    width = config['DISPLAY_WIDTH']
    spacer = bytearray([0x00, 0x00, 0x00])
    pacmans = [Pacman1, Pacman2]
    i = 0
    for step in range(0, width + len(spacer) + len(Pacman1[0]), frame_move):
        i += 1
        img_data = bytearray()
        for row_nr in range(height):
            prv_row = prv[row_nr * width:(row_nr + 1) * width]
            nxt_row = nxt[row_nr * width:(row_nr + 1) * width]
            row = prv_row + pacmans[i % 2][row_nr] + spacer + nxt_row
            img_data.extend(row[step:step + width])
        seq.add_frame(Frame(img_data, frame_delay))
    return seq
Exemple #13
0
 def _create_and_add_sequence(self,
                              catalog,
                              program_name,
                              sequence_content,
                              valid_time=None):
     seq = FrameSequence()
     # Frame(bytearray(b'Bar') * int(3456/3)
     seq.program = program_name
     if isinstance(sequence_content[0], Frame):
         seq.frames = sequence_content
     else:
         seq.frames = [
             Frame(bytearray(f.encode() * int(3456 / len(f))), 10)
             for f in sequence_content
         ]
     seq.valid_time = valid_time if valid_time is not None else Config(
     )['PROGRAM_RETIREMENT_AGE']
     catalog.add_program(program_name, seq)
     return seq
Exemple #14
0
 def typeset_3lines(self, seq: FrameSequence, msg: TextTripleLinesLayout)-> FrameSequence:
     font = FontMapping[msg.size]
     lines = msg.lines
     if not lines:
         return seq
     # lines = lines[0:3]  # Limit for now.
     image = bytearray()
     for line in lines:  # off all the lines
         MarkupLine(image, line, font)
     duration = msg.duration if msg.duration is not None else self.config['DISPLAY_DEFAULT_DELAY']
     if len(lines) <= 3:
         if len(lines) % 3 != 0:  # Append empty lines if not all lines are complete.
             missing_lines = 3 - len(lines) % 3
             for c in range(missing_lines):
                 MarkupLine(image, "", font)
         seq.add_frame(Frame(image, duration=duration))
     else:
         line_duration = msg.line_duration if msg.line_duration is not None else self.config['DISPLAY_LINE_DURATION']
         seq.extend(AnimateVerticalScroll(image, line_duration))
     return seq
Exemple #15
0
    def publishProgress(self):
        def _logFailure(failure):
            self.log.debug("reported {message}",
                           message=failure.getErrorMessage())
            return failure

        def _logAll(*args):
            self.log.debug("all publishing complete args={args!r}", args=args)

        # self.log.debug(" >< Starting one round of publishing >< ")
        now = datetime.now()
        seq = FrameSequence()
        image = bytearray()
        image.extend(self._create_graph_line(self._create_day_progress(now)))
        image.extend(self._create_graph_line(self._create_month_progress(now)))
        image.extend(self._create_graph_line(self._create_year_progress(now)))
        frame = Frame(image, duration=self.config['PROGRESS_DISPLAY_DURATION'])
        seq.add_frame(frame)
        seq.program = "progress"
        d = self.publish(topic=LEDSLIE_TOPIC_SEQUENCES_PROGRAMS[:-1] +
                         seq.program,
                         message=seq)
        d.addCallbacks(_logAll, _logFailure)
        return d