Пример #1
0
 def runprogram(self,filename:str,colour:Colour, inverted:bool,
                openmode:OpenTransition, displaymode:MessageStyle, closemode:CloseTransition):
     """ Program a usbfan device with a suitably formatted bitmap """
     m1=self.makemessage(filename,colour,openmode,displaymode,closemode,inverted)
     p = Program((m1,))
     d = Device()
     d.program(p)
 def test_checksum(self):
     self.assertEqual(Program.checksum(b'\x00\x40\x40\x01\xA2\x00\x00\x00'),
                      b'\x00\x40\x40\x01\xA2\x00\x00\x00\x23',
                      "checksum doesn't match reference data")
     self.assertEqual(Program.checksum(b'\x00\x40\x23\x80\x83\x80\x83\x80'),
                      b'\x00\x40\x23\x80\x83\x80\x83\x80\xE9',
                      "checksum doesn't match reference data")
     with self.assertRaises(ValueError):
         Program.checksum('abcdefgh')
     with self.assertRaises(ValueError):
         Program.checksum(b'aoeu')
Пример #3
0
    def example1(self):
        """ Example use """
        src="triangle.png"
        dst="testcvt6.png"
        pc=PovConvert()
        pc.OFFSET=180
        img=Image.open(src).resize((79,79),Image.BICUBIC)
        img=pc.getbwimage(img)
        img.save("tmp.png")
        img=pc.transformimage(img)
        img.save(dst)
        #pc.cvtimage(src,dst)
        print("Saved as ",dst)
        m4 = pc.makemessage(dst,Colour.cyan,OpenTransition.All,MessageStyle.Remain,
                            CloseTransition.UpDown,False)

        p = Program((m4,))
        d = Device()
        d.program(p)
    def test_small(self):
        columns = [Column([True] + [False] * 10, Colour.red)]
        for _ in range(7):
            columns.append(Column([False] * 11, Colour.red))
        f = Program((Message(columns), ))

        self.assertEqual(len(f), 1)
        self.assertIsInstance(f[0], Message)

        reference_message = (
            b'\x00\x40\x40\x01\x22\x00\x00\x00\xA3',
            b'\x00\x40\x23\xA4\x23\x9A\xA4\xA4\x0C',
            b'\x00\x40\x23\xA4\xA4\xA4\x84\xA4\x77',
            b'\x00\x40\x23\x84\xA4\x84\xA4\x84\x37',
            b'\x00\x40\x23\xA4\x84\xA4\x84\xA4\x57',
            b'\x00\x40\x23\x84\xA4\x84\xA3\xA4\x56',
            b'\x00\x40\x23\xA4\xA4\xA4\xA4\xA4\x97',
        )

        for data, reference in zip(f, reference_message):
            self.assertEqual(data, reference)
Пример #5
0
 def runscript(self,filename, defaults):
     """
     script format: filename colour inverted open display close
     Arguments left blank or with (-) will use defaults or command line values.
     # = comments
     """
     if defaults is None:
         defaults=argparse.Namespace()
         defaults.inverted=False
         defaults.open=OpenTransition.LeftRight
         defaults.close=CloseTransition.RightLeft
         defaults.display=MessageStyle.Anticlockwise
         defaults.colour=Colour.white
     messages=[]
     with open(filename,"r") as f:
         for line in f:
             line=line.strip()
             if line=="" or line.startswith("#"):
                 continue
             msg={}
             msg["filename"]=""
             msg["inverted"]=defaults.inverted
             msg["colour"]=defaults.colour
             msg["open"]=defaults.open
             msg["close"]=defaults.close
             msg["display"]=defaults.display
             args=line.split()
             msg["filename"]=args[0]
             if (len(args)>1 and args[1]!="-"): msg["colour"]=self.parseColour(args[1])
             if (len(args)>2 and args[2]!="-"): msg["inverted"]=self.parseBool(args[2])
             if (len(args)>3 and args[3]!="-"): msg["open"]=self.parseOpen(args[3])
             if (len(args)>4 and args[4]!="-"): msg["display"]=self.parseDisplay(args[4])
             if (len(args)>5 and args[5]!="-"): msg["close"]=self.parseClose(args[5])
             print("Building message: ",msg)
             messages.append(self.makemessage(msg["filename"],msg["colour"],
                                              msg["open"],msg["display"],msg["close"],
                                              msg["inverted"]))
     p = Program(messages)
     d = Device()
     d.program(p)
Пример #6
0
#! /usr/bin/env python3
# -*- coding: utf-8 -*-

from usbfan import Colour, Column, Device, Message, Program

# A generic "Message" is made up of 1 to 144 "Column" object
# A "Column" has 11 boolean pixels and a "Colour"
columns = [Column([True] + [False] * 10, Colour.red)]
for _ in range(7):
    columns.append(Column([False] * 11, Colour.red))
p = Program((Message(columns), ))

# Open the device and program
d = Device()
d.program(p)
Пример #7
0
        True if p >= 128 else False for p in img.convert('L').getdata(0)
    ]

    # Convert the image into its columns
    columns = [
        Column(img_data[i:i + Column.PIXELS], colour)
        for i in range(0, len(img_data), Column.PIXELS)
    ]

    return columns


def makemessage(imagename: str, color: Colour, openmode: OpenTransition,
                middlemode: MessageStyle, closemode: CloseTransition):
    return Message(buildimage(imagename, color), middlemode, openmode,
                   closemode)


m0 = makemessage("floral.png", Colour.blue, OpenTransition.DownUp,
                 MessageStyle.Anticlockwise, CloseTransition.UpDown)
m1 = makemessage("clockface.png", Colour.red, OpenTransition.DownUp,
                 MessageStyle.Flash, CloseTransition.DownUp)
m2 = makemessage("pattern.png", Colour.white, OpenTransition.Clockwise,
                 MessageStyle.Flash, CloseTransition.FromMiddle)

p = Program((m0, m1, m2))

# Open the device and program
d = Device()
d.program(p)
Пример #8
0
from usbfan import Colour, Column, Device, Message, Program

def sawtooth(i):
    j=i % 22;
    if j>=11: return 21-j
    return j

# A generic "Message" is made up of 1 to 144 "Column" object
# A "Column" has 11 boolean pixels and a "Colour"
columns=[]
rainbow_colours = [Colour.red, Colour.yellow, Colour.green,
                   Colour.cyan, Colour.blue, Colour.magenta]

for i in range(144):
    col = [True] * 11;
    col[sawtooth(i)]=False;
    columns.append(Column(col, rainbow_colours[i % 6]))
msg=Message(columns)
msg.openmode=Message.OPEN_DOWN_UP
msg.middlemode=Message.MIDDLE_CLOCKWISE
msg.closemode=Message.CLOSE_UP_DOWN
p = Program((msg,))

# Open the device and program
d = Device()
d.program(p)
Пример #9
0
#! /usr/bin/env python3
# -*- coding: utf-8 -*-

from usbfan import Device, Program, TextMessage

# A program is made up of a list of Messages
# A "TextMessage" is a subclass of the generic Message class
p = Program((
    TextMessage("Hello, World!"),
    TextMessage("How is everyone going?"),
))

# Open the device and program
d = Device()
d.program(p)
Пример #10
0
    MessageStyle, OpenTransition, CloseTransition

print("MAX_COLUMNS:", Message.MAX_COLUMNS, "x", Column.PIXELS)

# -> 144 * 11 pixel
# Column.PIXELS

# We can cycle the rainbow here and fill all 144 columns
rainbow_colours = [
    Colour.red, Colour.yellow, Colour.green, Colour.cyan, Colour.blue,
    Colour.magenta
]
rainbow = [
    Column([True] * 11, rainbow_colours[i % len(rainbow_colours)])
    for i in range(Message.MAX_COLUMNS)
]
p = Program((
    TextMessage("Hallo Maya & Fabian ...",
                message_style=MessageStyle.Flash,
                open_transition=OpenTransition.DownUp,
                close_transition=CloseTransition.DownUp),
    Message(rainbow,
            message_style=MessageStyle.Clockwise,
            open_transition=OpenTransition.FromMiddle,
            close_transition=CloseTransition.ToMiddle),
))

# Open the device and program
d = Device()
d.program(p)
Пример #11
0
    return columns


def makemessage(imagename: str,
                colour: Colour,
                openmode: OpenTransition,
                messagemode: MessageStyle,
                closemode: CloseTransition,
                inverted: bool = False):
    return Message(buildimage(imagename, colour, inverted), messagemode,
                   openmode, closemode)


m0 = makemessage("floral.png", Colour.blue, OpenTransition.DownUp,
                 MessageStyle.Anticlockwise, CloseTransition.UpDown)
m1 = makemessage("clockface.png", Colour.red, OpenTransition.DownUp,
                 MessageStyle.Flash, CloseTransition.DownUp)
m2 = makemessage("pattern.png", Colour.white, OpenTransition.Clockwise,
                 MessageStyle.Flash, CloseTransition.FromMiddle)
m3 = makemessage("clockface.png", Colour.yellow, OpenTransition.Clockwise,
                 MessageStyle.Clockwise, CloseTransition.ToMiddle, True)
m4 = makemessage("testcvt5.png", Colour.cyan, OpenTransition.Clockwise,
                 MessageStyle.Clockwise, CloseTransition.ToMiddle, False)

#p = Program((m0,m1,m2,m3))
p = Program((m4, ))

# Open the device and program
d = Device()
d.program(p)
Пример #12
0
for f in sys.argv[1:]:
    im = Image.open(f)

    if im.width > Message.MAX_COLUMNS or im.height != Column.PIXELS:
        print("Image format mismatch.")
        break

    img = []

    # walk over all pixels
    for x in range(im.width):
        # check for most prominent color in this column
        l = {}
        c = []
        for y in range(im.height):
            p = map(im.getpixel((x, y)))
            if p:
                if p not in l: l[p] = 1
                else: l[p] += 1
            c.append(p != None)

        img.append(Column(c, Colour.white if not l else max(l)))

    imgs = imgs + (Message(img), )

p = Program(imgs)

# Open the device and program
d = Device()
d.program(p)
Пример #13
0
#! /usr/bin/env python3
# -*- coding: utf-8 -*-

from usbfan import Colour, Column, Device, Message, Program, TextMessage

# We can cycle the rainbow here and fill all 144 columns
rainbow_colours = [Colour.red, Colour.yellow, Colour.green,
                   Colour.cyan, Colour.blue, Colour.magenta]
rainbow = [Column([True] * 11,
                  rainbow_colours[i % len(rainbow_colours)])
           for i in range(Message.MAX_COLUMNS)]
p = Program((
    TextMessage("Here comes the rainbow!"),
    Message(rainbow),
))

# Open the device and program
d = Device()
d.program(p)
Пример #14
0
def change_slide_event():
    global dev, dev_lock

    slide = request.json['indexh']
    print("Slide {}".format(slide))

    p = None
    if slide == 2:
        # Slide 2: "This" - "Hello CSides" - "Fri 19 Oct 2018"
        p = Program((
            TextMessage("This!"),
            TextMessage("Hello CSides"),
            TextMessage("Fri 19 Oct 18"),
        ))
    elif slide == 37:
        # Slide 37: "Single Red Dot"
        columns = [Column([True] + [False] * 10, Colour.red)]
        for _ in range(7):
            columns.append(Column([False] * 11, Colour.red))
        p = Program((Message(columns), ))
    elif slide == 44:
        # Slide 44: "Two Red Dots"
        columns = list()
        columns.append(Column([True] + [False] * 10, Colour.red))
        columns.append(Column([True] + [False] * 10, Colour.red))
        for _ in range(6):
            columns.append(Column([False] * 11, Colour.red))
        p = Program((Message(columns), ))
    elif slide == 47:
        # Slide 47: "Full Vertical Red"
        columns = [Column([True] * 11, Colour.red)]
        for _ in range(7):
            columns.append(Column([False] * 11, Colour.red))
        p = Program((Message(columns), ))
    elif slide == 49:
        # Slide 49: "Full Vertical Blue"
        columns = [Column([True] * 11, Colour.blue)]
        for _ in range(7):
            columns.append(Column([False] * 11, Colour.red))
        p = Program((Message(columns), ))
    elif slide == 51:
        # Slide 51: "Full Vertical Green"
        columns = [Column([True] * 11, Colour.green)]
        for _ in range(7):
            columns.append(Column([False] * 11, Colour.red))
        p = Program((Message(columns), ))
    elif slide == 61:
        # Slide 61: "Questions?" - RAINBOW!
        rainbow_colours = [
            Colour.red, Colour.yellow, Colour.green, Colour.cyan, Colour.blue,
            Colour.magenta
        ]
        rainbow = [
            Column([True] * 11, rainbow_colours[i % len(rainbow_colours)])
            for i in range(Message.MAX_COLUMNS)
        ]
        p = Program((
            TextMessage("Questions?"),
            Message(rainbow),
        ))

    if p:
        with dev_lock:
            dev.program(p)

    return ''
    def test_large(self):
        programs = list()
        for colour in (Colour.red, Colour.green, Colour.blue, Colour.yellow,
                       Colour.magenta, Colour.cyan, Colour.white):
            columns = [Column([True] + [False] * 10, colour)]
            for _ in range(14):
                columns.append(Column([False] * 11, colour))
            columns.append(Column([False] * 10 + [True], colour))
            programs.append(Message(columns))
        f = Program(programs)

        self.assertEqual(len(f), 7)
        self.assertIsInstance(f[6], Message)

        reference_message = (b'\x00\x40\x40\x02\x22\x01\x00\x00\xA5',
                             b'\x00\x40\x23\xA4\x1D\x92\xA4\xA4\xFE',
                             b'\x00\x40\x23\xA4\xA4\xA4\x80\xA4\x73',
                             b'\x00\x40\x23\x84\xA4\x84\xA4\x84\x37',
                             b'\x00\x40\x23\xA4\x84\xA4\x84\xA4\x57',
                             b'\x00\x40\x23\x84\xA4\x84\xA4\x84\x37',
                             b'\x00\x40\x23\xA4\x84\xA4\x84\xA4\x57',
                             b'\x00\x40\x23\x84\xA4\x84\xA4\x84\x37',
                             b'\x00\x40\x23\xA4\x84\xA4\x84\xA3\x56',
                             b'\x00\x40\x23\xA4\xA4\x92\xA4\xA4\x85',
                             b'\x00\x40\x23\xA4\xA4\xA4\x20\xA4\x13',
                             b'\x00\x40\x23\x24\xA4\x24\xA4\x24\x17',
                             b'\x00\x40\x23\xA4\x24\xA4\x24\xA4\x97',
                             b'\x00\x40\x23\x24\xA4\x24\xA4\x24\x17',
                             b'\x00\x40\x23\xA4\x24\xA4\x24\xA4\x97',
                             b'\x00\x40\x23\x24\xA4\x24\xA4\x24\x17',
                             b'\x00\x40\x23\xA4\x24\xA4\x24\xA3\x96',
                             b'\x00\x40\x23\xA4\xA4\x92\xA4\xA4\x85',
                             b'\x00\x40\x23\xA4\xA4\xA4\x60\xA4\x53',
                             b'\x00\x40\x23\x64\xA4\x64\xA4\x64\xD7',
                             b'\x00\x40\x23\xA4\x64\xA4\x64\xA4\x17',
                             b'\x00\x40\x23\x64\xA4\x64\xA4\x64\xD7',
                             b'\x00\x40\x23\xA4\x64\xA4\x64\xA4\x17',
                             b'\x00\x40\x23\x64\xA4\x64\xA4\x64\xD7',
                             b'\x00\x40\x23\xA4\x64\xA4\x64\xA3\x16',
                             b'\x00\x40\x23\xA4\xA4\x92\xA4\xA4\x85',
                             b'\x00\x40\x23\xA4\xA4\xA4\x00\xA4\xF3',
                             b'\x00\x40\x23\x04\xA4\x04\xA4\x04\xB7',
                             b'\x00\x40\x23\xA4\x04\xA4\x04\xA4\x57',
                             b'\x00\x40\x23\x04\xA4\x04\xA4\x04\xB7',
                             b'\x00\x40\x23\xA4\x04\xA4\x04\xA4\x57',
                             b'\x00\x40\x23\x04\xA4\x04\xA4\x04\xB7',
                             b'\x00\x40\x23\xA4\x04\xA4\x04\xA3\x56',
                             b'\x00\x40\x23\xA4\xA4\x92\xA4\xA4\x85',
                             b'\x00\x40\x23\xA4\xA4\xA4\x40\xA4\x33',
                             b'\x00\x40\x23\x44\xA4\x44\xA4\x44\x77',
                             b'\x00\x40\x23\xA4\x44\xA4\x44\xA4\xD7',
                             b'\x00\x40\x23\x44\xA4\x44\xA4\x44\x77',
                             b'\x00\x40\x23\xA4\x44\xA4\x44\xA4\xD7',
                             b'\x00\x40\x23\x44\xA4\x44\xA4\x44\x77',
                             b'\x00\x40\x23\xA4\x44\xA4\x44\xA3\xD6',
                             b'\x00\x40\x23\xA4\xA4\x92\xA4\xA4\x85',
                             b'\x00\x40\x23\xA4\xA4\xA4\xE0\xA4\xD3',
                             b'\x00\x40\x23\xE4\xA4\xE4\xA4\xE4\x57',
                             b'\x00\x40\x23\xA4\xE4\xA4\xE4\xA4\x17',
                             b'\x00\x40\x23\xE4\xA4\xE4\xA4\xE4\x57',
                             b'\x00\x40\x23\xA4\xE4\xA4\xE4\xA4\x17',
                             b'\x00\x40\x23\xE4\xA4\xE4\xA4\xE4\x57',
                             b'\x00\x40\x23\xA4\xE4\xA4\xE4\xA3\x16',
                             b'\x00\x40\x23\xA4\xA4\x92\xA4\xA4\x85',
                             b'\x00\x40\x23\xA4\xA4\xA4\xC0\xA4\xB3',
                             b'\x00\x40\x23\xC4\xA4\xC4\xA4\xC4\xF7',
                             b'\x00\x40\x23\xA4\xC4\xA4\xC4\xA4\xD7',
                             b'\x00\x40\x23\xC4\xA4\xC4\xA4\xC4\xF7',
                             b'\x00\x40\x23\xA4\xC4\xA4\xC4\xA4\xD7',
                             b'\x00\x40\x23\xC4\xA4\xC4\xA4\xC4\xF7',
                             b'\x00\x40\x23\xA4\xC4\xA4\xC4\xA3\xD6',
                             b'\x00\x40\x23\xA4\xA4\xA4\xA4\xA4\x97',
                             b'\x00\x40\x23\xA4\xA4\xA4\xA4\xA4\x97',
                             b'\x00\x40\x23\x64\xA4\xA4\xA4\xA4\x57',
                             b'\x00\x40\x23\xA4\xA4\xA4\xA4\xA4\x97')

        for data, reference in zip(f, reference_message):
            self.assertEqual(data, reference)